10. 指针
10.1 指针作用
指针变量是存储变量地址的变量,只能赋值地址,不能赋值其它,如给指针变量赋值整数,会发现报错。
10.2 指针占用空间
在32位操作系统下(X86),指针变量占用四个字节;
在64位操作系统下(X64),指针变量占用八个字节。
可见如下代码运行结果:
10.3 空指针
在初始化空指针的时候,其指向0地址,因为0-255是系统占用的内存,我们是没有权限访问的,因此会出现系统崩的情况。
10.4 野指针
指针随意指向某一个内存空间,可以将该内存地址强行编程指针类型,
但是当我们对该地址内容进行操作时,就会系统报错。
所以我们程序中不要出现野指针,它不是我们申请的内存,就没有访问权限。
10.5 Const修饰指针
//常量指针,常量的指针,可以改变指向,但是不可以改变指向的内容。Const *,*代表指针。
const int* p =&a;
//指针常量,指针的常量,指针是常量,可以改变指向的内容,但是不可以改变指向。* const
int* const p = &b;
//
const int* const p = &c;
10.6 指针和数组
用指针来访问数组的元素。
这里定义的指针p是int型的,所以p++即是偏移4个字节,进而指向下一个数组元素。
10.7 指针和函数
当在函数中要对数组进行操作时,一定要传递数组长度,因为在函数中不能测量此数组长度。如下:
这里的形参是一个指针类型,只占有四个字节,它只是代表一个地址,是数组首地址,并不是数组名字,所以在函数中测量不了数组长度。
10.8 地址传递
值传递是仅仅传递实参的值到形参,因此不影响实参的值。
但是地址传递,是可以改变实参的值。
原理如下:
11. 结构体
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。
代码运行结果如下:
11.1 结构体数组
相当于将结构体当成一个数据类型,类似于int arr[10];只不过这里的数组元素是一个结构体({}里面的元素一个结构体类型)。
代码运行如下:
在进行运算的时候,可以直接像int型数组那样,进行运算,可以赋值,不可以进行加减。
11.2 结构体指针
用一个指针指向结构体,把结构体类比成一个如int型的数据类型。
11.3 结构体嵌套结构体
结构体的一个成员是结构体类型。
11.4 结构体作为函数参数
将结构体当成一种函数类型,然后可以进行值传递和地址传递。
同样是值传递不能改变实参的值,地址传递可以。
如代码运行所示,图中五点注意项。
11.5 结构体数组作为函数参数
当函数参数需要是结构体数组的时候,有两种方法,
第一种方法是指针:
这个时候操作数组元素,就要使用指针->进行操作,t++。
第二种方法:数组名访问:
当然当访问数组结构体时,可以不用指针,可以直接使用数组名字,因为数组名也是代表地址。只不过要加[ ]。告诉函数,这个是数组。如图所示:
这样就可以直接访问数组内的各个元素了。
11.6 Const修饰结构体
值传递的缺点是要开辟出一段和实参相同的数据内存,当数据量比较大的时候,就比较占用内存。因此常常不会使用值传递,而是采用地址传递,因为无论什么数据类型,指针只占用四个字节,用来存储地址,大大的节省了内存空间,但是会由于误操作,改变实参的值。这个时候就可以在形参前加一个const.如图所示: