C++Primer第四版第四章要点总结!

第四章 数组和指针

4.1 数组

  • 数组的长度是固定的,而无法直接知道一个给定数组的长度。数组一经创建,就不允许添加新的元素
  • 没有所有元素都是引用的数组,即数组元素不能是引用。
  • 在函数体外定义的内置数组,其元素均初始化为 0
  • 在函数体内定义的内置数组,其元素无初始化
  • 不管数组在哪里定义,如果其元素为类类型则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。
  • 不能用一个数组初始化另一个数组。
int a[2] = {1,2};
int b[2];
b = a; //非法操作
  • 数组支持随机访问,默认下标从0开始。

4.2 指针

  • & 取地址操作符只能用于左值。
  • 指针只能指向同类型的对象。
  • 如果需要在一个声明语句中定义两个指针,必须在每个变量标识符前再加符号 * 声明
int a = 3;
int *p1, *p2;               //定义了两个int类型的指针
int *p3, p4;                //定义了一个int型的指针p3和一个int变量p4
p1 = &a;                    //p1指针指向a变量
std::cout << *p1 <<endl;    //输出p所指向变量的值
  • void 类型的指针可以指向任意类型的变量*,该类型指针不能操纵他所指向的对象。仅支持以下操作:
    1.与另一个指针进行比较.
    2.作为参数或者函数的返回值.
    3.给另一个 void* 指针赋值
  • 指针和引用的区别:
    1.引用在定义时必须初始化,且它不能修改
    2.给引用赋值是修改该引用关联对象的值,给指针赋值是使指针指向新的对象,原指向对象的值不改变。
int a = 1, b = 2;
int *p1 = &a, *p2 = &b;
p1 = p2;                //现在p1指向了b变量
int &r1 = a, &r2 = b;
r1 = r2;                //此时b的值被赋给a
  • 在指针上加上(或减去)一个整型数值 n 等效于获得一个新指针,
    该新指针指向指针原来指向的元素之后(或之前)的第 n 个元素。
  • 允许在指针上加减0,使指针保持不变。更有趣的是,如果一指针具有 0 值(空指针),则在该指针上加 0 仍然是合法的,结果得到另一个值为 0 的指针。
    也可以对两个空指针做减法操作,得到的结果仍是 0。 - 用指针遍历数组
const int N = 5;
int a[N] = {0, 1, 2, 3, 4};
//p1指向数组第一个元素,p2指向最后一个元素之后的那个位置。
for(int *p1 = a, *p2 = a + N; p1 != p2; ++p1)
    cout << *p1 <<" "; 
  • 指向const对象的指针:const限定的是指针cp所指向的对象类型,而不是指针本身,可以修改使其指向另一个const对象,但不允许修改其所指对象的值。
  • 不能使用“void*”指针保存const对象的地址,必须使用“const void*” 指针。
const int a = 1;
int b = 2;
const int c = 3;
const int *cp;      //这里指针cp指向一个int类型的const对象,也就是说该指针只能指向const的对象
cp = &a;            //合法
cp = &b;            //非法,该指针只能指向const对象
cp = &c;            //合法
int *p2;
p2 = &a;            //非法,不能将一个const对象的地址赋给一个非const对象的指针。
  • const指针:该指针不可修改,但是该指针指向对象的值是可以修改的const指针也必须在定义时初始化。任何试图给const指针赋值的行为都不合法(及时用它自己给自己赋值)。
int a = 1, b = 2;
int *const p = &a;
*p = 3;             //合法
p = &b;             //非法
  • 指向const对象的const指针:既不能修改该指针,又不能修改该指针所指向的对象的值
typedef string *pstring;
const pstring cstr;
  • 上例不能理解为 const string *cstr;而应该理解为 string *const cstr;

4.3 C风格字符串

  • C++ 语言通过(const)char*类型的指针来操纵 C 风格字符串。
  • 常用C风格字符串操作函数(需包含头文件 #include ):
函数描述
strlen(s)返回s的长度,不包括字符串结束符。
strcmp(s1, s2)若s1==s2,返回0;s1>s2,返回正数;否则返回负数。
stract(s1, s2)将s2连接到s1末尾,返回s1
strcpy(s1, s2)将s2赋值给s1
strncat(s1, s2, n)将s2前n个字符连接到s1后面,返回s1
strncpy(s1, s2, n)将 s2 的前 n 个字符复制给 s1,并返回 s1
  • strlen总是假定其参数字符串以null字符结束,若不是则会出错。
char ca[] = {'C', '+', '+'};    //没有null结束符
cout << strlen(ca) << endl;     //出错,不能这样使用
  • 每一个程序在执行时都占用一块可用的内存空间,用于存放动态分配的对象,此内存空间称为程序的自由存储区或堆。在自由存储区中创建的数组对象是没有名字的,只能通过地址访问。
int *pia = new int[10];     //分配了一个含有10元素的数组,并将数组首指针返回给pia
  • 动态分配数组时,如果数组元素具有类类型,将使用该类的默认构造函数实现初始化;如果数组元素是内置类型,则无初始化。也可使用跟在数组长度后面的一对空圆括号,对数组元素做值初始化。对于动态分配的数组,其元素只能初始化为元素类型的默认值,而不能像数组变量一样,用初始化列表为数组元素提供各不相同的初值。如果我们在自由存储区中创建的数组存储了内置类型的const对象,则必须为这个数组提供初始化
int *pia2 = new int[10] ();     //初始化为0
// 错误,未初始化const对象
const int *pci_bad = new const int[100];
// 正确
const int *pci_ok = new const int[100]();
  • C++ 允许定义类类型的const数组,但该类类型必须提供默认构造函数。
  • C++ 虽然不允许定义长度为0的数组变量,但调用 new 动态创建长度为0的数组是合法的。new动态创建长度为0的数组时,new返回有效的非零指针。该指针与new 返回的其他指针不同,不能进行解引用操作,因为它毕竟没有指向任何元素,可以进行比较,加0,减去自身得到0。
  • C++ 语言为指针提供delete[]表达式释放指针所指向的数组空间,如果遗漏方框会产生内存泄漏,发生严重错误。
int *p = new int[n]();
delete [] p;
  • string 类型的加法操作需要两个操作数,可以使用 C 风格字符串作为其中的一个操作数,也允许将C风格字符串用作复合赋值操作的右操作数。反之:在要求C 风格字符串的地方不可直接使用标准库 string 类型对象。如无法使用string对象初始化字符指针
string s2("he");
char *str = st2;            //错误
char *str = st2.c_str();    //使用c_str()函数可以完成赋值,该函数返回指向字符数组首地址的指针
  • 可以用数组初始化vector
const size_t arr_size = 6;
int int_arr[arr_size] = {0, 1, 2, 3, 4, 5};
// ivec has 6 elements: each a copy of the corresponding element in int_arr
vector<int> ivec(int_arr, int_arr + arr_size);
vector<int> ivec(int_arr + 1, int_arr + 4);

4.4多维数组

int ia[3][4] = {
    {0,1,2, 3},
    {4,5,6,7},
    {4,5,6,7}
};       //声明并且初始化一个三行四列的二维数组

int ib[3][4] = {0, 3, 6, 9};        //该声明初始化了第一行的元素,其余元素都被初始化为 0。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值