- 1、数组
数组声明: typename arrayname[arraysize]
或者 在声明时候赋值 int x[2]={1,2};
如果只对数组的一部分进行初始化,则编译器会把其他元素设置为0,因此:
long tio[5]={10};
如果初始化时方括号内【】为空,编译器自动计算元素个数:
short totals[ ]={1,2,3}
注意:arraysize指定元素的数目 ,必须是整型常数或者const值,具体来说,arraysize不能是变量。当然可以使用new运算符来避开这种限制。
访问数组元素:arrayname[i] i从0开始,到size-1
c++11 初始化数组时,省略等号 doouble x[2] {1,2};
可以不再大括号中包含任何内容 doouble x[2] {} ,这将会把所有元素设为0
c++的标准模板库提供了一种数组替代品 -模板类vector,c++11新增了array。
- 字符串
c++处理字符串方式有两种 一种来自c语言,另一种基于string类库的方法。
c语言风格字符串性质:以空字符结尾 ,空字符 \0,其ascii码为0.
char dog[3] ={‘b’,’e’,’\0′} //字符串
char cat[3] ={‘a’,’v’,’d’} //字符数组
char bird[11] = “mr. cheepes” //注意“”里不用显示的包括\0,但隐式的包括空字符,所以数组大小必须比实际长度大于一个以上。
使用键盘输入字符串时,将自动加上空字符
注意:字符串常量(” “)不能与字符常量(’ ‘)互换。”s”表示字符串,是由’s’和’\0’组成,而’s’表示单个字符。
字符串输入:
cin>>name; cin使用空白(空格、制表符、换行符)来确定字符串结束的位置,因此cin在读取 字符串时只能读取一个单词,然后将其放到数组name中。
为了解决上面的问题,将整个一行字符作为输入:istream中cin提供了类成员函数:getline()和get(),读取输入,直到遇到换行符后才停止。区别 getline() 将丢弃换行符,get将保留换行符在输入队列中。
cin.getline(name,size)
name:存储的数组名,size:读取的字符数,如果size=20,那么最多读取19个字符,且不hi存储最后的换行符,余下空间用于自动存储\0空字符。
cin.get( name,size )
混合输入字符串和数字
- string类
包含头文件 <string>,string类位于std命名空间中,必须使用using编译指令或者使用std::string引用它。
定义: string str1; string str2=”sssssss”;
赋值: cin>>str1;
显示:cout<<str1
通过访问数组的方法访问string ,str1[3]
string和字符数组区别:可以将 string对象声明为简单变量,而不是数组。声明时候不用指定大小。
c++11 初始化string : string one={“dddfse”}; string two{“sdhfhs”}
string赋值、拼接和附加 string str2 =str1 string str3 =str1+str2
c中ctring头文件中的函数 strcpy(chaar1,charr2) //copy charr2 to charr1 strcat(charr1,charr2) 拼接charr2到charr1中
string的输入输出 cin cout,当读取一行时,使用的方法不同:
数组字符串: cin.getline(charr,20)
string: getline(cin,str1)
- 结构体
创建该类型变量 : inflatable hat;
可以将结构作为参数传递给函数,也可以让函数返回一个结构,可以使用 = 将一个结构赋给同类型的结构。
可以在定义结构体同时创建结构变量,只需要将变量名放在定义 结构的括号后面。
结构数组
- 共用体 union
共用体是一种数据格式,能够存储不同的数据类型 ,但只能同时同时存储其中的一种类型。
声明 和struct类似
- 枚举 enum ,可以替代 const,还允许定义新类型
enum spectrum {red,orange,yellow,green,blue,violet,indigo,ultraviolet};
默认情况下,将整数值赋给枚举变量 ,第一个枚举值为0,以此类推。当然也可以显式指定整数来覆盖默认值。
枚举只有 赋值运算,没有算数运算。
如果使用 整数:需要强制类型转换 枚举名(整数)
设置枚举值
- 指针、数组
地址运算符 &变量 获得该变量的地址
指针:用于存储值的地址,使用*运算符,可以得到该地址处的值,*被称为间接值运算符,即 x是一个地址,*x时该地址的数值
可以在命名的同时赋值:
int *p
声明一个指针:
int *p or int* p or int*p
可以在声明的同时初始化: int * p= &x
注意:初始化的是 p,而不是*p
new运算符
delete 释放内存
int *p = new int
delete p
注意:只能用delete删除new分配的内存
使用 new来新建动态数组
指针小结
- 数组名是一个指针,指向的是数组array[0]
- 将&用于数组名时候,获得的是整个数组的内存地址,因此需要取 &array[0]作为数组指针的地址
指针和字符串
C++处理字符串有两种方式,即:指针方式和数组方式
数组方式:char a[] = “HelloWorld”;
指针方式:const char* s = “HelloWorld”; const可以忽略
接下来详细讲解一下字符串指针
首先,为什么字符串可以直接赋值给指针,即char* s = “HelloWorld”不会报错,不应该是把字符串的地址赋值给指针吗?
原因:这里的双引号做了3件事:
1.申请了空间(在常量区),存放了字符串
- 在字符串尾加上了’/0′
3.返回地址
为什么字符串指针的指针名输出字符串内容而不是地址?
字符串指针的指针名代表字符串的首地址,但输出字符串指针名时输出的却是完整字符串,如下:
char* s = "HelloWorld";
cout<<s<<endl; //s是字符串的首地址,但却输出HelloWorld
cout<<*s<<endl; //输出H
cout<<*(s+1)<<endl; //输出e,s+1是第二个字符的地址
cout <<static_cast<void *>(s) << endl; //此时输出的才是字符串地址
原因是C++标准库中I/O类对<<操作符重载,在遇到字符型指针时会将其当作字符串名来处理,输出指针所指的字符串。既然这样,那么我们就别让它知道那是字符型指针,所以得用到强制类型转换,用static_cast把字符串指针转换成无类型指针
字符串指针指向的地址可以修改,但所指向的字符串内容不能修改,因为字符串常量是不能改变的
char* s = "HelloWorld";
s="abcd"; //合法
cout<<*(s+1)<<endl;
*(s+1)='d'; //不合法,这里虽然没报错,但这一句实际下一句并未执行
cout<<s<<endl; //未执行
字符串指针数组:
char *p[6]={"ABCD","EFGH","IJKL","MNOP"};
int i;
for(i=0;i<4;i++)
cout<<p[i]<<endl; //输出每个字符串,实际上p[i]为第i个字符串的首地址
for(i=0;i<4;i++)
cout<<*p[i]; //输出每个字符串第一个字符AEIM
cout<<endl;
for(i=0;i<4;i++)
cout<<*(p[i]+1); //输出每个字符串第二个字符BFJN
C++中使用char*定义字符串,不能改变字符串内的字符的内容,但却可以把另外一个字符串(新地址)赋值给它,即p1是一个char型指针变量,其值(指向)可以改变;此时,若指向的新地址为字符串数组的地址,则可更改字符串中的内容
使用new创建动态结构:
类型组合