数组:
初始化: typeName arrayName[arraySize]; arraySize 必须是整型常量或者const值;
必须是特定类型的数组: int数组、char数组、float数组;
只对数组一部分进行初始化,编译器把其他元素设置为0;
C++标准模板库(STL)一种数组替代品----模板类vector
字符串:
char数组存储字符串以空字符 ' ' 结尾;
char dog[5] = {'b'. 'e'. 'a'. 'u'. 'x'}; // not a string!
char cat [5] = {'f'. 'a'. 't'. 's'. ' '}; // a string!
字符串常量初始化:
char bird[10] = "Mr. Cheeps"; // the is understood
char fish[] = "Bubbles"; // let the compiler count
注意: 字符串常量(使用双引号)不能与字符常量(使用单引号)互换。
在ASCII系统上,'S'只是83的另一种写法;
"S"表示的是两个字符(S和 字符)
标准头文件 cstring 提供了标准库函数 strlen() 计算字符串长度;
cin使用空白(空格、制表符和换行符)来定字符串的界,因此只能读取一个单词;
面向行的输入: getline():
cin.getline (name, 20);
第一个参数用来存储输入行的数组的名称,第二个参数是要读取的字符数;
通过回车输入的换行符来确定输入结尾
面向行输入:get():
第一种:cin.get (name, ArSize); 参数解释与cin.getline() 相同,但是不能跨越换行符!!!;
第二种:cin.get() 可以读取下一个字符;
cin.get (name, ArSize);
cin.get (); 等效于 cin.getline (name, ArSize);
cin.get (dessert, ArSize); cin.getline (dessert, ArSize); 等效于 cin.getline (name, ArSize).getline (dessert, ArSize);
iostream类的成员函数get() 函数经常应用于cin.get (name, ArSize) .get()
string类简介:
string类型的变量---对象, 头文件为string,string类位于名称空间std中;
类的设计能让程序自动处理string的大小,可以避免char数组存储容不下等问题;
相比于char数组存放字符串:
string对象可以对象间赋值; str1 = str2
可以使用 '+' 将两个string对象合并; str3 = str1 + str2
可以使用 '+=' 实现string对象拼接 str1 += str2
str.size():
size() 是类string的一个类方法(即成员函数), 成员函数只能通过所属类的对象进行调用;
str1.size() 确定对象str1中字符数; 头文件string // string类头文件
strlen(charr1) 确定char数组charr1中字符数; 头文件cstring // C-style string library
getline(cin, str):
这里的 getline() 不是类的方法(cin.getline() 由对象调用的才是类的方法);
cin作为参数指出到哪里去找输入
结构简介:
结构的声明与初始化:
struct inflatable inflatable gust = { { char name[20]; "Glorious Gloria", float volume; 1.88, double price; 29.99 }; };
C++不提倡使用外部变量,但提倡使用外部结构声明(所有函数可以用这种类型的结构)。
结构可以作为参数传递给函数,可以让函数返回一个结构,可以用操作符 '=' 将结构赋给另一个同类型的结构
结构数组:
可以创建元素为结构的数组: inflatable gifts[100];
其中 gifts 是数组、gifts[0] ~ gifts[99] 是结构,存在gifts[0] .name、gifts[0] .volune、gifts[0] .price;
共用体:
共用体句法与结构相似,但是公用体只能同时存储一种数据类型
用途之一: 当数据项使用两种或更多格式(但不会同时使用)时,可以节省空间;
枚举:
可以代替const,另一种创建符号常量的方式 enum工具;
enum spectrum {red, orange, yellow, green, blue, violet, indigo, ultraviolet};
spectrum 为新类型名称,将red、orange、 yellow等作为符号常量0~7,成为枚举量;
在不进行强制类型转换的情况下,只能将定义时使用的枚举量赋值给枚举变量:
spectrum band; // 声明枚举变量
band = blue; // valid,将枚举量blue赋给band
band = 2000; // invalid,2000不是枚举量
枚举量是整型,可被提升为int类型,但int 不能被自动转换为枚举类型
指针和自由存储空间:
计算机在存储数据时要跟踪的三个基本属性:
信息存储在何处、存储的值为多少、存储的信息是什么类型;
策略:
1. int a = 1;声明语句指出了值的类型和符号名,程序为值分配内存,并在内部跟踪该内存单元;
2. 将地址设为指定的量,将值设为派生量,指针---用于存储值的地址,' * ' 号操作符被称为间接值或解除引用
假设manly表示的是一个地址,而*manly表示存储在该地址处的值。这里的*manly相当于int变量a
在C++ 中 int* 是一种复合类型,是指向 int 的指针;
int higgens = 5;
int *pt = &higgens; // 将 pt (而不是 *pt)的值设置为&higgens, 而*pt = 5
指针与数组一样是基于其它类型的,我们应说指向double的指针(double*)、指向char的指针(char*)、指向int类型的指针(int*);
指针的危险:
典型的危险:
long * fellow; // 声明long指针,未初始化
* fellow = 223323; // 数据被一个未初始化地址的指针指向
指针使用的金科玉律:
一定要在对指针应用解除引用操作符(*)之前,将指针初始化为一个确定的、适当的地址。
指针和数字:
指针不是整型,要将数字值作为地址来使用赋值给指向 int 的指针(int*),应通过强制类型转换
int *pt; pt = ( int* ) 0xB8000000; // 不能直接 pt = 0xB8000000;
使用 new 来分配内存:
int * pn = new int, 通用格式: typeName pointer_name = new typeName;
pn指向的内存没有名称,使用 *pn 操作 pn 指向的数据对象;
计算机没有足够内存时, new 返回0,C++中值为0的指针被称为空指针。如果成功,new 返回一个有用的指针;
使用 delete 来释放内存:
int *ps = new int; // 使用 new 获得内存; . . . // 使用内存; delete ps; // 使用 delete 释放内存
释放 ps 指向的内存,但不会删除 ps 本身;
配对的使用 new 和 delete,防止内存的泄露;
C++ 指出不要尝试释放已经释放的内存块;
对空指针使用 delete 是安全的;
使用 new 创建动态数组:
静态联编: 通过声明来创建数组,在程序被编译时将为它分配内存空间;
动态联编: 数组在程序运行时创建并确定数组的长度;
使用 new 创建一个包含10个 int 元素的动态数组, 在类型名后加上方括号,其中包含元素数目:
int * psome = new int [10];
new 操作符返回第一个元素的地址;
使用 new 创建的数组,应使用 "delete [ ] psome" 释放一个数组
new 和 delete 使用时,应遵守规则:
1. 不用使用 delete 来释放不是 new 分配的内存;
2. 不要使用 delete 释放同一个内存块两次;
3. 使用 new [ ] 为数组分配内存,则应使用 delete [ ] 来释放;
4. 使用 new [ ] 为一个实体分配内存,则应使用 delete (没有方括号)来释放;
5. 对空值指针应用 delete 是安全的
使用动态数组:
C和C++内部都是使用指针来处理数组,数组与指针基本等价是C和C++的优点之一;
int * psome = new int [10] :
*psome 是第一个元素的值;
psome[0] 为第一个元素、psome[1] 为第二个,依次类推----把指针当做数组名即可
指针与数组的不同之处:
数组名的值是不能修改的,但指针是变量,可以修改;
psome = psome + 1 将使得表达式 psome[0] 指向数组的第二个值
指针小结:
(1)声明指针
typeName * pointerName; 声明指向特定类型的指针
(2)给指针赋值
可以对变量名应用 '&' 操作符来获得被命名内存的地址,new 操作符返回未命名内存的地址:
double * pn; // 定义指向double类型的指针pn;
double * pa; // 定义指向double类型的指针pa;
char * pc; // 定义指向char类型的指针pc;
double bubble = 3.2;
pn = &bubble; // 把bubble的地址给指针pn;
pc = new char; // 分配指向新的指向char地址的内存给pc;
pa = new double[30]; // 分配元素为30的double数组地址给pa;
(3)解除指针引用
1. 对指针应用解除引用或间接值操作符 (*) 来解除引用: *pn = 3.2;
2. 数组表示法: pn[0] 与 *pn 是一样的
注意: 绝不要对未初始化为适当地址的指针解除引用
(4)数组名
C++将数组名视为数组的第一个元素的地址:
int tacos[10]; // 此时 tacos 等同于 &tacos[0]
sizeof 操作符用于数组名时,返回整个数组的长度(单位为字节)
(5)指针算数
C++允许将指针和整数相加,加1的结果等于原来的地址值加上指向的对象占用的总字节数;
两个指针指向同一个数组时,可以将一个指针指向另一个指针,得到两个元素的间隔
(6)数组的动态联编和静态联编
使用数组声明来创建数组时,将采用静态联编,即数组的长度在编译时设置:
int tacos[10] ;
使用 new[ ] 操作符创建数组时,将采用动态联编,即在运行时为数组分配空间。 使用这种数组后,应使用delete [ ] 释放占用的内存:
int * pz = new int [size];
. . .
delete [ ] pz;
(7)数组表示法和指针表示法
使用方括号的数组表示法等同于对指针解除引用;
tacos 等同于 *tacos
tacos[3] 等同于 *(tacos + 3)
使用数组表示法时,C++执行转换:
arrayName[i] 转换 *(arrayName + i);
使用指针表示法时,C++执行转换:
pointerName[i] 转换 *(pointerName + i)
指针和字符串:
在cout和多数C++表达式中,char数组名、指向char的指针以及用双引号括起来的字符串常量都被解释为字符串第一个字符的地址:
char flower[10] = "rose"; // 声明指向char的数组,并赋初值
cout << flower << "s are red "; // 输出 roses are red 数组名flower和字符串常量"s are red "都被解释为第一个字符地址
将 animal 数组中的字符串复制到新分配的空间:
ps = new char[strlen (animal) + 1]; // get new storage "+1" 是因为字符串存储有' '
ps = animal; // invalid 不会复制字符串,只复制地址,这样两个指针ps 和animal 将指向相同地址
strcpy (ps, animal); // valid copy string to new storage;通过使用strcpy() 和new 将获得两个独立的副本
注意:应该使用strcpy() 或strncpy() ,而不是复制操作符来讲字符串赋给数组
使用new创建动态结构:
“动态”意味着内存在运行时而不是编译时分配;
将new用于结构有两步组成:创建结构和访问成员:
创建:intflatable *ps = new inflatable;
访问:1. 指针用操作符(->) eg: ps->name 2. 结构名用句点操作符 eg: (*ps).price
复合类型总结:
数组、结构和指针是C++3种复合类型;
数组可以在一个数据对象中存储多个同类型的值,通过使用索引或者下标可以访问数组中各个元素;
结构可以将多个不同类型的值存储在同一个数据对象中,可以使用成员关系操作符(.)来访问其中的成员
1. 创建模板,定义结构存储了那些成员;
2. 根据模板声明相应类型的结构变量。
共用体可以存储一个值,但这个值可以是不同的类型,成员名指出了使用的模式;
指针被设计是用来存储地址的变量,指针声明指出了指针指向的对象的类型,对指针使用解除引用操作符可以获得值;
字符串是以空字符结尾的一系列字符:
字符串可以用双引号括起来的字符串常量表示,其中隐式的包含了结尾的空字符;
可以将字符串存储在char 数组中;
可以用被初始化为指向字符串的char指针表示字符串;
函数strlen()返回字符串的长度,不包括空字符。函数strcpy()将字符串从一个位置复制到另一个位置。头文件cstring。
new操作符允许程序在运行时为数据对象请求内存。该操作符返回获得内存的地址,可以将这个地址赋给一个指针:
如果数据对象是简单的变量,可以使用解除引用操作符(*)来获取真值;
如果数据对象是数组,可以像使用数组名那样使用指针来访问元素,ps[0]、ps[3];
如果数据对象是结构,可以使用指针解除引用操作符(->)来访问成员。
指针和数组关系紧密:
ar[i] 被解释为 *( ar + i )数组名ar被解释为数组的第一个元素;
同样可以使用数组表示法,通过指针来访问new分配的数组中的元素。
自动变量是在函数中声明的变量,而静态变量是在函数外部或者使用关键字 static声明的变量