? ? 指针就是地址。
? ? 数据是存储在存储介质里的,比如内存和外存。存储介质里有很多存储单元,想要在存储单元里放数据,就需要知道某个存储单元在哪里,而想要知道在哪里,就得要有这个存储单元的地址。
? ? 也就是说,一个地址对应一个存储单元,通过地址就可以找到存储单元,也就是找到数据。
? ? 声明一个变量:int a。int 一般四个字节,所以a会占据内存中某一块大小为四字节的连续空间。
? ? &a代表变量a的地址,也就是这片空间的头存储单元的地址。
? ? 声明一个指针变量:int *b。*b就是一个指针,如果:b=&a,就是将a的地址给了b,那么b的值就是a的地址值。
? ? 那么*b就是在通过a的地址找到a的值,那么*b的改变,a也就会改变。
? ? int c(int d);这是一个函数的声明,它接受一个整型的变量。
? ? 函数传参有一个特点,比如c(a),在c的函数体中,a的值是多少,d的值就是多少,因为d的值就是a传过去的。
? ? 但a和d有本质上的不同,那就是它们的地址不同。这就是实参和形参的区别。
? ? 有时候我们希望传过去的就是a,在函数体中的各种操作就是在操作a。那么就需要把a的地址传过去,而不是传a的值。
? ? 重新声明函数c:int c(int *d);
? ? 现在,d是一个指针了,那么它就应该指向一个地址。因此传参时就需要把a的地址传过去,c(&a)。
? ? 这样,操作d就是在操作a的地址。
? ?有时候,实参是一个指针:
? ? int *a;int b=0;a=&b;我们也希望可以在函数体中直接操作传过来的参数。
? ?&a是指针a的地址,a是b的地址,*a是b的值。
? ?c(a);这样是在传b的地址。
? ? 若函数是这样的:int c(int *d);
? ? 就是在说让d等于b的地址。可也仅仅如此而已,d只是d,a只是a,b也只是b,它们的地址都不同。
? ? 若函数是这样的:int c(**d);
? ? 传的是a的地址;c(&a);
? ? d就等于a的地址,*d就等于b的地址(因为a等于b的地址),那么**d就是b的值。
? ? 于是在函数中,操作*d就是在操作b的地址,也是在操作a。
? ? 简单来说,传的是一般变量的地址,用一重指针就可以实际操作参数。传的是指针的地址,用二重指针就可以实际操作参数。
? ? 只有传地址,才能改变实参的值。