此文为自己的一些理解和看法,如有错误,请各位大佬指出。
C指针
C中每个变量都有一个内存空间,每一个内存空间都有自己的地址,我们可以对变量使用 & 来获取变量地址,如下所示:
//运行代码
#include<stdio.h>
int main() {
int num = 1;
float fnum = 2.1f;
char letter = 'a';
printf("num 的地址为 %p\n", &num);
printf("fnum 的地址为 %p\n", &fnum);
printf("letter 的地址为 %p\n", &letter);
return 0;
}
//运行结果
num 的地址为 000000CE34B6FB54
fnum 的地址为 000000CE34B6FB74
letter 的地址为 000000CE34B6FB94
何为指针
指针是一个变量,它的值为另一个变量的地址,即,内存空间的直接地址。我们在使用指针存储其他变量地址之前,先进行声明。
DataType *ptr;
//DataType为变量类型,ptr为指针名称
int *iptr; /*整型指针*/
float *fptr; /*float型指针*/
char *cptr; /*字符型指针*/
所有数据类型对应指针的值的类型都是一样的,都是一个代表内存地址的十六进制数。
不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
指针的使用
创建一个指针iptr存储num的地址。其中对指针使用星号*获取指针指向的值。
#include<stdio.h>
int main() {
int num = 1;
int* iptr = #
printf("变量 num 的值为 %d\n", num);
printf("指针 iptr 所指向的值为 %d\n", *iptr);
printf("变量 num 的地址为 %p\n", &num);
printf("指针 iptr 所存储的地址为 %p\n", iptr);
return 0;
}
变量 num 的值为 1
指针 iptr 所指向的值为 1
变量 num 的地址为 000000A1E514F594
指针 iptr 所存储的地址为 000000A1E514F594
函数参数
当调用函数时,把实参的值复制给形参,然后函数用形参来进行相关操作。在函数内形参的值变化并不会影响实参的值变化。
#include<stdio.h>
void test(int num) {
printf("test中 num的值为%d 地址为%p\n", num, &num);
}
int main() {
int num = 1;
printf("main中 num的值为%d 地址为%p\n", num, &num);
test(num);
return 0;
}
main中 num的值为1 地址为000000D6EA4FFC24
test中 num的值为1 地址为000000D6EA4FFC00
可以看出当函数调用时,形参只是复制了实参的值,它们的内存地址是不一样的。
所以当形参改变自己的值时,相应的实参是不会变化的。
#include<stdio.h>
void test(int num) {
printf("test中 num的值为%d 地址为%p\n", num, &num);
num = 2;
printf("test中 num的值为%d 地址为%p\n", num, &num);
}
int main() {
int num = 1;
printf("main中 num的值为%d 地址为%p\n", num, &num);
test(num);
printf("main中 num的值为%d 地址为%p\n", num, &num);
return 0;
}
main中 num的值为1 地址为000000062894FA04
test中 num的值为1 地址为000000062894F9E0
test中 num的值为2 地址为000000062894F9E0
main中 num的值为1 地址为000000062894FA04
test函数内改变num的值时,是对形参num操作,因此实参num的值仍为1。
指针作为函数参数
为何函数需要指针作为参数呢?
从上面可以看出,当我们想用test函数对main中的num值进行修改时,其实main中的num是没有变化的。如果我们想要通过函数操作改变main中num值时,该怎么操作呢?这就需要指针来进行相关的操作,从而实现我们的需求(ps:当然我们也可以通过return返回我们需要的值)。
为什么通过指针能修改实参值
我们通过下面的一个例子来说明
#include<stdio.h>
void test(int *num_ptr) {
printf("test中 num_ptr存储的地址为%p 所指向的值为%d\n", num_ptr, *num_ptr);
*num_ptr = 2;
printf("test中 num_ptr存储的地址为%p 所指向的值为%d\n", num_ptr, *num_ptr);
}
int main() {
int num = 1;
printf("main中 num的地址为%p 值为%d\n", &num, num);
test(&num);
printf("main中 num的地址为%p 值为%d\n", &num, num);
return 0;
}
main中 num的地址为000000943AB2F6B4 值为1
test中 num_ptr存储的地址为000000943AB2F6B4 所指向的值为1
test中 num_ptr存储的地址为000000943AB2F6B4 所指向的值为2
main中 num的地址为000000943AB2F6B4 值为2
此时test的实参为num的地址,形参num_ptr复制的是num的地址。虽然在函数中对形参的值进行改变时,实参不会受到影响。但有趣的是,num_ptr的值是地址,当我们通过修改此指针指向的内容时,num_ptr还是存储的是num的地址,num的地址没有收到影响但num值已经改变。
举个例子,把实参当一把钥匙,形参当做另外配的钥匙。
在函数内你重新改造形参钥匙(即更改内容),实参钥匙没有影响。
如果这时候有一个房间,实参是房间的钥匙(指针为钥匙,指向的内存为房间),由于形参钥匙与实参钥匙一样,故通过形参钥匙可以修改房间的布局(修改指向的内存内容)。当函数执行完后,形参钥匙被丢弃,房间布局已改变。
如果拿到形参钥匙,对钥匙进行改造,形参钥匙就只能开另外一个房间。而原房间不受影响。
一句话
形参只是复制实参的值,形参如何变化不管实参的事。但形参通过指针修改指向的内容,就会影响实参所指向的内容,虽然此时形参和实参的值一样。