- 数组(array)是一种数据格式,能够存储多个同类型的值。
- 每个值存储在独立数组元素中,在内存中连续存储各个元素
- 创建数组,使用声明语句
- 数组声明包括:存储在每个元素中值的类型、数组名、数组中元素数
- 通用格式:typeName arrayName [arraySize]; arrarSize必须整型常数,不能是变量
- 单独访问数组元素的方法是使用下标或索引对元素编号。
- C++数组从0开始编号,最后一个元素的索引比数组长度少1
//程序清单4.1 //整数数组 #includeint main (void) { using namespace std; int yams[3]; //创建包含三个元素的int类型数组 yam[0] = 7; //给每个元素赋值 yam[1] = 8; yam[2] = 6; int yamcosts[3] = {20, 30, 5]; //创建和初始化数组 cout << "Total yams = " << yams[0] + yams[1] + yams[2] << endl; cout << "The package with " << yams[1] << " yams costs " << yamcosts[1] << " cents per yam.n"; int total = yams[0] * yamcosts[0] + yams[1] * yamcosts[1] + yams[2] * yamcosts[2]; cout << "The total yam expense is " << total << " cents.n"; cout << "nSize of yams array = " << sizeof yams << " bytes.n"; //12 bytes cout << "Size of one element = " << sizeof yams[0] << " bytes.n"; //4 bytes return 0; }
- 程序给yam赋值和给yamcost赋值采用了两种方法
- sizeof运算符返回类型或数据对象的长度(单位为字节)
- 只有定义数组时才能使用初始化,此后不能使用,也不能将一个数组赋值给另一个数组;可以使用下标分别给数组元素赋值
int cards[4] = {3, 6, 8, 10}; //可以 int hand[4]; //可以 hand[4] = {5, 6, 7, 8}; //不可以 hand = cards; //不可以
- 初始化时提供的值可以小于数组元素数目,编译器将剩余元素设置为0
- 将数组所有元素初始化为0,只需显式地将第一个元素初始化为0
- 如果初始化为{1}而不是{0},则第一个元素被设置为1,其余元素为0
- 如果初始化数组是【】为空,则C++编译器计算元素个数
- 数组初始化,可省略=
- 字符串常量(双引号,字符+ )——字符串地址
- 字符常量(单引号,字符)——ASCII码
//程序清单4.2 //在数组中存储字符串 #include#include //为了使用strlen()函数 int main (void) { using namespace std; const int Size = 15; char name1[Size]; char name2[Size] = "C++owboy"; cout << "Howdy! I'm " << name2 << "! What's your name?n"; cin >> name1; //Basicman cout << "Well, " << name1 << ", your name has " << strlen(name1); //8 letters cout << " letters and is stored in an array of " << sizeof(name1) << " bytes.n";//15 bytes cout << "Your initial is " << name1[0] << ".n"; //B name2[3] = ''; cout << "Here are the first 3 characters of my name: " << name2 << endl; //C++ return 0; }
- sizeof运算符指出整个数组的长度:15字节;strlen()函数返回存储在数组中字符串的长度,不算空字符在内
- 此程序有个缺陷:cin使用空白(空格、制表符、换行符)确定字符串结束位置。如果输入输入的是pin duoduo,程序只是读取pin到name1中,将duoduo 保留在输入队列。此时要用面向行的输入:getline()和get()
//程序清单4.4 4.5 //getline() 和get() #includeint main (void) { using namespace std; const int ArSize = 20; char name[ArSize]; char dessert[ArSize]; cout << "面向行的输入:getline()" << endl; cout << "Enter your name:n"; cin.getline(name, ArSize); cout << "Enter your favorite dessert:n"; cin.getline(dessert, ArSize); cout << "I have some delicious " << dessert << " for you, " << name << ".n"; cout << "面向行的输入:get()" << endl; cout << "Enter your name:n"; cin.get(name, ArSize).get(); cout << "Enter your favorite dessert:n"; cin.get(dessert, ArSize).get(); cout << "I have some delicious " << dessert << " for you, " << name << ".n"; return 0; }
- getline()函数读取整行,通过换行符确定行尾,但不保存换行符,在存储字符串时,用空字符替换换行符
- get()函数读取整行,但保存换行符在队列中,用不带任何参数的get()处理换行符
cin.get(name, ArSize); cin.get(); //或 cin.get(name, ArSize).get();
- 该函数们有两个参数。第一个参数用来存储数组名称,第二个参数读取字符数。如果第二个参数为20,则最多读取19个字符,余下留给空字符。但cin.get()有多种参数形式,也可以没有参数get(),后面再说
//程序清单4.6 //以下数字输入与行输入 #includeint main (void) { using namespace std; cout << "What year was your house built?n"; int year; cin >> year; cout << "What is its street address?n"; char address[80]; cin.getline(address, 80); cout << "Year built: " << year << endl; cout << "Address: " << address << endl; return 0; }
该程序运行如下:
What year was your house built?
1966
What is its street address?
Year bulit: 1966
Address:
- 用户根本没有输入地址的机会。问题在于:cin读取年份,将回车键生成的换行符保留在输入队列中。后面的cin.getline()看到换行符后,认为是一个空行,将空字符串赋值给address数组
- 解决之道是:读取地址前先读取并丢弃换行符
cin >> year; cin.get(); //或 (cin >> year).get();string类
//程序清单4.7 //使用C++ string 类 #includeint main(void) { using namespace std; char charr1[20]; char charr2[20] = "jaguar"; string str1; string str2 = "panther"; cout << "Enter a kind of feline: "; cin >> charr1; cout << "Enter another kind of feline: "; cin >> str1; cout << "Here are some felines:n"; cout << charr1 << " " << charr2 << " " << str1 << " " << str2 << endl; cout << "The third letter in " << charr2 << " is " << charr2[2] << endl; cout << "The third letter in " << str2 << " is " << str2[2] << endl; return 0; }
- 要使用string类必须包含头文件string。string类位于名称空间std中,必须提供using编译指令
- string类隐藏了字符串的数组性质,能够像处理普通变量一样处理字符串
- 通过示例可知,在很多方面,使用string对象的方式与使用字符数组相同
- string对象和字符数组之间主要区别是:可以将string对象声明为简单变量,而不是数组
- 类设计可以让程序自动处理string大小
- 不能将一个数组赋值给另一个数组,但可以将一个string对象赋值给另一个string对象
char charr1[20]; char charr2[20] = "jaguar"; string str1; string str2 = "panther"; charr1 = charr2; //非法 str1 = str2; //合法
- string类简化了字符串合并 *** 作。使用运算符+将两个string 对象合并,也可以使用+=将字符串附加到string对象末尾
- C++新增string类之前,程序员使用C语言库中函数完成。头文件cstring提供了这些函数,strcpy()将字符串复制到字符数组中,strcat()将字符串附加到字符数组末尾
string str3; str3 = str1 + str2; //合并 str1 += str2; //拼接 strcpy(charr1, charr2); //复制charr2 给charr1 strcat(charr1, charr2); //将charr2内容附加到charr1末尾
- string对象语法通常比C字符串函数简单
str3 = str1 + str2; //一句 strcpy(charr3, charr1); strcat(charr3, charr2); //两句
- string类具有自动调整大小的功能,C函数库需要使用strncpy()和strncat()
//程序清单4.10 //行输入 #include#include #include int main(void) { using namespace std; char charr[20]; string str; cout << "Length of string in charr before input: " << strlen(charr) << endl; cout << "Length of string in str before input: " << str.size() << endl; //不确定,0 cout << "Enter a line of text:n"; cin.getline(charr, 20); //peanut butter cout << "You enter: " << charr << endl; cout << "Enter another line of text:n"; getline(cin, str); //blueberry jam cout << "You enter: " << str << endl; cout << "Length of string in charr after input: " << strlen(charr) << endl; cout << "Length of string in str after input: " << str.size() << endl; //13,13 return 0;
- 首先初始化数组内容是未定义的,其次函数strlen()从数组第一个元素开始计算字节数直到遇到空字符。未被初始化的数据,第一个空字符出现的位置是随机的
- str中字符串长度为0,是因为未被初始化的string对象长度被自动设置为0
- cin.getline(charr, 20); 这种句点表示法表明,函数getline()是istream类的一个类方法
- getline(cin, str); 这里没有使用句点表示法,表明这个getline()不是类方法
- 结构是一种比数组更灵活的数据形式,同一个结构,可以存储多种类型的数据。
- 关键字struct表明这些代码定义的是一个结构的布局。
- 标识符inflatable是这种数据格式的名称。
- 大花括号中包含的是结构存储的数据类型的列表,其中每个列表项都是一条声明语句。
//程序清单4.11 //一个简单的结构体 #includestruct inflatable //结构体声明 { char name[20]; float volume; double price; }; int main(void) { using namespace std; inflatable guest = {"Glorious Gloria", 1.88, 29.99}; inflatable pal = {"Audacious Arthur", 3.12, 32.99}; cout << "Expand your guest list with " << guest.name << " and " << pal.name << "!n"; //Expand your guest list with Glorious Gloria and Audacious Arthur! cout << "You can have both for $" << guest.price + pal.price << "!n"; //You can have both for .98! return 0; }
- C++允许在声明结构变量时省略关键字struct。
- 由于guest和pal的类型为inflatable,因此可以使用成员运算符(.)来访问各个成员。
- 通过成员名能够访问结构的成员,就像通过索引能够访问数组的元素一样。
- guest是一个结构,而guest.price是一个double变量。
- 结构体一般放在main函数前面。
- C++不提倡使用外部变量,但提倡使用外部结构声明。
- 和数组一样,使用由逗号分隔值列表,并将这些值用花括号括起。
- 与数组一样,c++11也支持将列表初始化用于结构,且等号(=)是可选的。
- 如果大括号内未包含任何东西,各个成员都将被设置为零。
- 还可以使用赋值运算符(=),将结构赋给另一个同类型的结构。这种赋值被称为成员赋值。
//程序清单4.13 //结构数组 #includestruct inflatable { char name[20]; float volume; double price; }; int main(void) { using namespace std; inflatable guest[2] = //初始化结构数组 { {"Bambi", 0.5, 21.99}, //注意逗号 {"Godzilla", 2000, 565.99} }; //注意分号 cout << "The guest " << guest[0].name << " and " << guest[1].name << "nhave a combined volume of " << guest[0].volume + guest[1].volume << " cubic feet.n"; return 0; }
- 数组中每个元素都是结构类型的结构体。guest[2]是一个包含两个inflatable结构的数组。
- 共用体是一种数据格式,它能够存储不同的数据类型,但只能同时存储其中的一种类型。
- 结构可以同时存储int 、long和double;共用体只能存储int、 long或double。
- 共用体的句法与结构相似,但含义不同:
union one4all { int int_val; long long_val; double double_val; };
- 可以使用one4all变量来存储int、 long或double,条件是在不同的时间进行。
- 共用体常用于(但并非只能用于)节省内存。常用于 *** 作系统数据结构或硬件数据结构。
- C++的enum工具,提供了另一种创建符号常量的方式。这种方式可以代替const。
- 使用enum的方法与使用结构相似。
enum spectrum {red, orange, yellow, green, blue, violet, indigo, ultraviolet};
- 这条语句完成两项工作:
- 让spectrum成为新类型的名称。spectrum被称为枚举。就像struct变量被称为结构一样。
- 将red,orange,yellow等作为符号常量,它们对应整数值0~7,这些常量叫做枚举量。
band = blue; //合法 band = 2000; //非法
- 只能在花括号枚举范围内取值。
band = orange; //合法 ++band; //非法 band = orange + red; //非法
- 对于枚举只定义了赋值运算符,具体的说没有为枚举定义算术运算符。
int color = blue; //合法,枚举类型提升为int band = 3; //非法,int不能转换为枚举 color = 3 + red; //合法,red转换为int
- 枚举量是整型,可以被提升为int类型,但int类型不能自动转化为枚举类型。
- 可以认为int类型比枚举类型高级,可以提升,但不能降低。
band = spectrum(3); //将int类型3强制转换为枚举类型
- 如果int值是有效的(在枚举允许范围内),则可以通过强制类型转换,将它赋给枚举变量。
- 可以用赋值运算符来显式的设置枚举量的值。
enum bits {one = 1, two = 2, four = 4, eight = 8};
- 指定的值必须是整数。也可以只显式的定义其中一些枚举量的值。
enum bigstep {first, second = 100, third};
- 这里first在默认情况下为零。后面没有被初始化的枚举量的值将比前面的枚举量大1。因此third的值为101。
- 可以创建多个值相同的枚举量
enum {zero, null = 0, one, numero_uno = 1};枚举的取值范围 指针和自由存储空间
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)