1、野指针:就是指针指向的位置是不可知的,指向的位置可能不能访问,触发段错误
2、怎么避免野指针:在指针解引用之前,要确保指针指向一个绝对可用的空间
常规做法:第一点:在定义指针时同时初始化为NULL;
第二点:在解引用之前先判断这个指针是不是NULL;
第三点:使用完后再将其赋值为NULL;
第四点:在使用指针前,先将其赋值绑定一个可用的地址空间。
3、NULL到底是什么
在C/C++中定义为:
#ifdef _cplusplus
#define NULL 0
#else
#define NULL (void *)0
#endif
为什么将指针指向0地址处?第一:0地址作为一个特殊地址(我们认为指针指向这个地址就表示指针没有被初始化,就表示野指针);第二:0地址在一般的操作系统中都是不可被访问的,如果不按规矩直接去解引用就会触发段错误,这已是最好的结果了。
4、const关键字,用来修饰变量,并表示这个变量是常量
第一种:const int *p;
第二种:int const *p;
第三种:int * const p;
第四种:const int * const p;
关于const修饰的变量的理解,主要涉及两个变量:第一个是指针变量p本身;第二个是p指向的那个变量的值(*p)
5、数组中a和&a不能做左值,因为a代表整体的数组空间,对数组操作要单独操作,不能整体操作;&a是一个编译器自动分配的好的内存地址,所以是个常量,不能做左值。
6、&a、a、&a[0]从数值上是相同的,但从意义上看,a和&a[0]是数组首元素的首地址,而&a是整个数组的首地址;从类型来看,a和&a[0]是元素指针,也就是int*类型的;而&a是数组指针,是int (*)[]类型的。这个区别对指针运算会产生影响。
7、指针变量+1时实际吧不是+1而是加1*sizeof(指针类型),主要原因是希望指针+1后刚好指向下一个元素。
(一个字节占8个bit(0x00),所以一个int类型的就占32个字节(0x0000))
8、函数形参是数组时,实际传的不是整个数组,而是数组的首元素首地址,实际上相当于传递的是指针,也就是占4个字节。所以传递数组大小时要另外将sizeof(a)传进函数中,表示数组大小。
9、在子函数内传参得到的数组首元素首地址和外面直接得到的数组首元素的首地址是相同的,这就叫做“传址调用”,此时可以通过穿进去的地址来访问实参。,数组作为函数形参时,[ ]里的数字可有可无,这是因为数组名做形参传递的只是个指针,根本就没有数组长度这个信息。
10、结构体变量作为函数形参的时候,实际和普通变量时表现一样。由于结构体一般比较大,所以也用指针来传参。
11、传值调用