c++ 复合类型

  • 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.申请了空间(在常量区),存放了字符串

  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创建动态结构:

类型组合

模板类 vector 和 array

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注