【共读Primer】10.<2.3> 复合类型 Page45

C++的复合类型 引用和指针

引用就像是类型的别名

int ival = 1024;
int &refVal = ival;
// int &refVal2 ; // 报错:引用必须被初始化
int &refVal1 = ival, &refVal2 = ival, &refVal3 = refVal1, Val4=ival;
// refVal1/refVal2/refVal3都是引用,其中refVal3用另一个引用进行初始化
// Val4是一个int它并不是引用

指针的初步认识

不管是否学过C或者C++对于指针这个东西只要是接触过计算机语言的,我相信都会对这个东西有所耳闻。

强大、底层、无限制、容易出错、容易崩溃、难以使用

让C/C++程序员又爱又恨的东西。

我认为,指针确实存在他的弊端,但是反过来想一下,如果你有足够的能力掌握它,那么它只会帮助你。

就像手枪,警察拿着它维护治安,军人拿着它保家卫国,匪徒则拿着它打家劫舍。

区中的区别不是手枪本人,而是持有它的人,或者准确的说是持有者的想法和做法。

指针同样有这个特性,在粗细大意的程序员手中,永远是噩梦.......

产品发布前一天,最后一次测试验证,却发现一个95%客户都会使用的功能频繁的导致软件崩溃。
最后检查到时指针使用问题。
只做了一个小小的修改,但是突然发现程序怎么运行都不对,不是结果偏离预期就是无缘无故的崩溃。

我想这类问题不是我一个人遇到过,有些项目经验,特别是进入过问题攻关团队的人一定深有体会。

下面来介绍一下指针最基础的知识,请注意领会。

int *ip1, *ip2; // ip1和ip2都是指向int性对象的指针
double dp, *dp2; // dp2是指向double型对象的指针,dp是double型对象

// 如何对一个指针类型进行初始化
int ival = 42;
int *p = &ival; // p存放变量ival的地址,或者说p是指向变量ival的指针

double dval;
double *pd = &dval; // 初始化是double型对象的地址
double *pd2 = pd;    // 初始值是指向double对象的指针

int *pi = pd;     // 错误 类型不匹配
pi = &dval;       // 错误,依然是类型不匹配的原因

int ival = 42;int *p = &ival; // p存放着变量ival的地址,或者说p是指向变量ival的指针std::cout << *p; //由符号*得到指针p所指向的对象,输出42*p = 0;  // 由符号*得到指针p所指向的对象,即可精油p为变量ival赋值std::cout << *p;  // 输出0

int *p1 = nullptr;   // 等价于 int  *p1 = 0; 将指针赋值为空,代表一个空指针// nullptr 是C++11中新引入的,如果没有对C++11支持请按照如下写法int *p3 = NULL;

指针的四种状态:

1. 指向一个对象

2. 指向紧邻对象所占空间的下一个位置

3. 空指针, 没有指向任何对象

4. 无效指针, 上述情况以外的其他情况

第四种情况是引发程序崩溃的唯一指针相关原因,编译器没有办法检查这种错误,所以必须靠程序员自己完成验证。

而第二和第三种情况,虽然有效,但是行为是受限的,所以不要试图访问这些指针。

我的建议,对于初学者来说需要详细掌握指针的每种特性细节,

在使用的时候要胆大心细,不要因噎废食。
因为永远记住一句话,如果不想犯错最好的方法是什么也不做,但是你同时也放弃了进步的可能。
多做多错这句话没错,而且很有道理,只是看你怎么去理解。

接下来介绍两个比较绕口的类型

1. 指向指针的指针

int ival = 1024;
int *pi = &ival;   // pi指向一个int型的数
int **ppi = &pi;  // ppi指向一个int型的指针

2. 指向指针的引用

int i = 42;
int *p;         // p是一个int型的指针
int *&r = p; // r是一个对指针p的引用

r = &i;         // r引用了一个指针,因此给r赋值&i就是令p指向i
*r = 0;        // 解引用r得到i,也就是p指向的对象,将i的值改为0

与指针或引用相关的表达式的阅读顺序一般是从右向左的。

原文地址:https://www.cnblogs.com/ChattyKu/p/9412961.html

时间: 2024-08-06 02:26:30

【共读Primer】10.<2.3> 复合类型 Page45的相关文章

C++Primer快速浏览笔记-复合类型

C++Primer2.3节介绍了两种复合类型:引用和指针 1.引用 引用并非对象,它只是为一个已经存在的对象所起的别名. 一旦初始化完成,引用将和它的初始值对象一直绑定在一起,不能重新绑定到另一个对象,因此引用必须初始化. 定义引用时,程序把引用和它的初始值绑定到一起,而不是将初始值拷贝给引用. 引用本身不是一个对象,所以不能定义引用的引用 引用只能绑定在对象上,而不能与字面值或者某个表达式的结果绑定在一起. 引用的类型必须和与之绑定的对象的类型严格匹配.但是有两种例外情况: 1.初始化常量引用

【共读Primer】64.[7.3]类类型 Page249

类类型 对于类来说每个类的定义都是唯一的类型,即使两个类的成员完全一样,他们仍然是不同的类型 struct First { int memi; int getMem(){return memi;}; }; struct Second { int memi; int getMem(){return memi;}; }; First obj1; Second obj2 = obj1; // 两个不同的类型无法进行赋值操作 类的声明 同函数一样,类也可以只声明而不定义,这种语法的常用场景是在使用类的地

[C++ Primer Plus] 4、复合类型(一)程序清单

程序清单4.1 1 #include<iostream> 2 using namespace std; 3 4 void main(){ 5 int yams[3]; 6 yams[0]=7; 7 yams[1]=8; 8 yams[2]=6; 9 int yams_cost[3]={20,30,5}; 10 11 cout<<"Total yams="<<yams[0]+yams[1]+yams[2]<<endl; 12 cout<

【共读Primer】8.&lt;2.1&gt; 基本内置类型(2) Page32

虽然C++中的类型是强制声明的,但是这并不意味着不同类型之间不可以进行一些计算或赋值. 我们来看下面的一组代码 1 #include <iostream> 2 3 int main() 4 { 5 bool b = 42; 6 int i = b; 7 double pi = i; 8 unsigned char c = -1; 9 signed char c2 = 256; 10 std::cout << "bool b =" << b 11 &l

【共读Primer】20.&lt;3.6&gt; 多维数组 Page112

C++中的多位数组,严格来说是数组的数组. int ia[3][4]; //大小为3的数组,每个元素是含有4个整数的数组 // 大小为10的数组,每个元素都是大小为20的数组, // 这些数组的元素是含有30个整数的数组 int arr[10][20][30] = {0}; // 将所有元素初始化为 0 初始化多维数组 int ia1[3][4] = { {0,1,2,3}, {4,5,6,7}, {8,9,10,11} }; // 以下语句等价于上面的初始化 int ia2[3][4] = {

[C++ Primer Plus] 5、复合类型(二)课后习题

1.编写一个 c++ 程序,如下述输出示例所示的那样请求并显示信息 : What is your first name? Betty SueWhat is your last name? YeweWhat letter grade do you deserve? BWhat is your age? 22Name : Yewe, Betty SueGrade : CAge: 22 1 #include<iostream> 2 using namespace std; 3 4 void main

【共读Primer】3.&lt;1.3&gt;注释简介 Page8

C++的注释有两种 1.  双斜杠开始到本行结束 (//) 2. 斜杠星开始 星斜杠结束 (/*)(*/) 1 #include <iostream> // 标准库中输入输出流的库名称 2 /* 3 * 简单主函数: 4 * 读取两个数,求它们的和 5 */ 6 int main() 7 { 8 std::cout << "Enter two numbers:" << std::endl;// 输出一个提示信息的字符串,并在结尾换行 9 int v1

【共读Primer】19.&lt;3.5&gt; 数组-C风格字符串 Page109

C风格的字符串是指以空字符'\0'结尾的一个字符串. 这种字符串虽然在C++中兼容,但是极易引起内存安全问题,所以不建议使用. 但是作为一个语言特性,我们应该了解它,这样才能在碰到的时候做到心中有数. 3.5.4 C标准库string函数 这里所说的string函数并不是std::string的函数,而是在C的标准库中,对C风格字符串进行操作的一些全局函数. strlen(p); //计算p的长度,不计入空字符结尾 strcmp(p1, p2); // 比较两个字符串p1和p2是否相等,相等返回

【共读Primer】35.&lt;5.2&gt;语句作用域 Page155

在if .switch. while 和for语句的控制结构内定义的变量只在其结构内部可见,超出结构范围将变为未定义. 1 #include <iostream> 2 #include <vector> 3 4 using std::cout; 5 using std::endl; 6 7 std::vector<int> v = {1,2,3,4,5,6,7,8,9}; 8 9 10 int get_num() 11 { 12 return 1; 13 } 14 15