复合类型
数组
typename arrayname[arraysize]
数组被称为复合类型,因为是使用其他类型创建的。(c语言使用术语“派生类型”)
例如
1 | float loans[20]; |
loans类型叫做“float数组”。
数组初始化时,如果只对一部分初始化,编译器将其他元素设置为零。
如果初始化时[]为空
1 | short things[]={1,5,3,8}; |
编译器使things包含四个元素。
字符串
c-风格字符串基本功能
存储在char数组中,c-风格字符串以空字符结尾,空字符结尾为\0.其ASCII码为0。尽量避免将不是字符串的字符数组当做字符串处理。数组表达字符串也可以这样表达。
1 | char bird[11]="Mr.Cheeps"; |
引号括起的字符串自带结尾空字符。
注:字符串常量(使用双引号)不能与字符常量(使用单引号)互换。字符常量’S’在ASCII系统中,只是83的另一种写法,而“S”代表的是(字符S和\0)组成的字符串。“S”实际上是字符串所在地址。由于地址是一种独立的类型,所以c++禁止将地址赋值。
c-风格字符串操作
strlen():计算字符串的长度
strcpy():复制字符串。
strcat():连接两个字符串。
sort():对数组进行排序。
search():在数组或字符串中搜索特定元素或字符。
字符串输入问题
cin在输入字符串时使用空白(空格、制表符和换行符)来确定结束位置,遇到多个单词cin无法正常读取。
如果要读取完整的一串带有空格的字符串,需要用到getline()与get(),两个函数遇到换行符才结束输入。
cin.getline(name,num)
注意需要留一位插入空字符。
get()
与getline()不同,get不在读取并丢弃换行符。而是留在输入队列中。可以采取cin.get()空过。
注意:在使用cin>>year;等表达式时,换行符会保留。此时调用getline()会导致读取空行,输出空字符串。此时就需要cin.get()进行空过。
string类
string类的赋值与拼加,str=str1+str2;可直接直观拼加。
str.length()返回字符串长度。
要想在输出有“”号,需要在引号开头使用“+结尾使用+”
结构体
1 | strcut inflatable{ |
这里创建了像char或int一样的变量,在后续代码可以创建inflatable的变量,大括号中是结构存储的数据类型。可以相同也可以不相同。
struct inflatable a;
inflatable a;
这两种定义方式都正确。
如果要访问结构体中的部分数据类型通过“ . ”来访问。inflatable.name[i]就是name数组中存储部分。以此类推。
注意:inflatable.name相当于输出数组全部。
1 | struct{ |
没有名字的结构体仍然合法。在括号后面就是以此结构体为变量的声明。声明可以有多个,但是在下面的语句中无法再定义这种结构体。
同样的结构体数组也是被允许的。
共用体(先略过)
指针和自由存储空间
指针本身是一个变量,存储的是值的地址。而不是值本身。只需要对变量应用地址运算符(&),就能获得位置。例如home是一个变量,&home使其存储数值的地址。*运算符被称为间接值,或是解除引用运算符。
int *a=&home;就是创建一个指向home地址的指针变量。
int*是一种类型—-指向int的指针。但是
int*p1,p2;是创建一个指针加上一个int变量。
对于每一个指针变量名,都需要使用一个*。
指针、数组与指针算术
整数变量加一,其值增加一。指针变量加一,增加的量等于他指向的类型的字节数。指向double的指针加一,若使用8个字节存储,数值加八。这说明一点:c++将数组名解释为地址。
因此根据这一特性,可以通过指针运算来访问整个数组。
循环及其表达式
for循环
for循环组成
for(initialization; test-expression; update-expression)
body
循环体可以包含一条语句,也可以使用复合语句或代码块包含多条语句。
test-expression(测试表达式)决定循环体是否被执行。update-expression(更新表达式)。
c与c++不同之处在于,c++可在initialization处直接声明变量。但上述for语句因不适用原来的句法,最初只是定义了新的表达式-声明语句表达式来合法化,现在for句法修改如下:
for(for-init-statement condition;expression statement)(其实没差,为了满足语句和表达式的差异,由于for-init-statement condition自带;所以就没有了特意定义新的表达式问题)。
递增运算符(++)和递减运算符(–)
++c; c++;存在两种写法。虽然两者对于操作数一致但是影响的时间不同。
为了方便解释++、–运算符生效规定。需要引入副作用和顺序点的概念。副作用指的是计算表达式时对某些东西进行了修改;顺序点是程序执行的一个点。在c++中,一个“;”就是一个顺序点。此外,任何完整表达式的末尾也是一个顺序点。
例
1 | while(guests++<10){ |
首先,输出的guests是在while循环语句中执行了++的guests。其次++通过使用后缀形式,确保guests先与10进行比较后再讲值加1。
应该尽量避免的代码形式
1 | y=(4+x++)+(6+x++); |
上文讨论过,以;为顺序点,所以在计算过程中x的值什么时候发生改变是无法判断的。所以执行程序时可能会出现未知问题。
c-风格字符串比较
若word为数组名
word==”mate”并非预想中进行工作。因为数组名是数组的地址。引号括起的字符串常量也是地址,所以上述并非字符串比较,而是地址比较。所以即使是相同字符串其地址仍不相同。
如果要进行字符串的比较,需要用strcmp()函数解决。函数可接受二者地址为参数,这说明参数可以是指针、字符串常量或字符数组名。实际上strcmp函数是通过比较每个字符的ASCII码返回差值确定最终输出的,所以比较的不是字符串的长度问题,而是字符串总字符编码差。
比较string类字符串
与c-风格字符串不同,string类字符串实现了重载运算符,可直接用”==” “!=”进行判断,相比上述更简单直观。
while循环
while(test-condition)
body
for与while
二者几乎等效,对于任意的while循环,可以改写为for循环形式。
while(test-expression)
body
for(;test-expression;)
body
for与while区别主要在于continue语句。但默认无法知道确定循环次数时,采用while语句。
延时循环
1 | long wait=0; |
该代码在计算器处理器速度变化,也相应随之改变。此外有些编译器会将wait设为1000,要想实现延时循环,最好用系统时钟完成。
函数clock()
需要头文件ctime,