印度小哥讲解的指针, 真的很好, 这里附上链接:
https://www.bilibili.com/video/BV1bo4y1Z7xf/?spm_id_from=333.999.0.0
1. 什么时候一个函数需要返回指针
注意:指针说白了也只不过是一种数据类型, 所以函数返回一个指针当然也是没有任何问题的.
函数返回指针的主要目的是为了提高效率、避免复制大对象、实现资源共享或多态性等。在使用指针时,务必注意内存管理和资源释放,以避免内存泄漏或其他问题.
1.1 代码实例
这样输出的代码其实是不对的, 因为先执行的 Add函数后执行的printfHelloworld函数
, 当 Add函数
执行完之后会自动进行销毁, 那么有可能 Add函数
的在 栈
上的内存空间已经被释放掉了, 随后被 printfHelloworld 函数
覆盖了, 之后, main函数栈帧
中的 ptr返回原来指向的空间的时候
那个空间中存储的已经不是原来的值了, 所以有可能打印出错.
void printfHelloWorld() {
printf("hello, world\n");
}
int* Add(int* a, int* b) {
//printf("Add函数中a的地址为:%p\n", &a);
//printf("main函数中a的地址为:%p\n", a);
//printf("Add函数中a指向的值为:%d\n", *a);
int c = (*a) + (*b);
return &c;
}
int main() {
int a = 2;
int b = 4;
//printf("main函数中a的地址为:%p\n", &a);
int* ptr = Add(&a, &b);
printfHelloWorld();
printf("sum = %d", *ptr);
return 0;
}
1.2 这个代码实例的意义
- 表示从
栈底
向上传递参数是没有任何问题的, (从栈底
向上传递一个局部变量或者一个局部变量的地址是可以的). - 但是从
栈顶
向下传递一个一个局部变量的地址是不可以的. (返回值通常存储在寄存器中,而不是栈上。因此,即使函数的栈帧被销毁,返回值仍然可以被安全地传递)
1.2.1 什么时候可以使用返回地址呢?
- 在全局变量区域有一个“变量”就可以.
- 在堆中开辟空间可以, 毕竟堆中的空间是需要手动释放的, 只要自己不进行释放就是固定的位置, 不会有问题.
1.2.2 修正之后的代码
void printfHelloWorld() {
printf("hello, world\n");
}
int* Add(int* a, int* b) {
//printf("Add函数中a的地址为:%p\n", &a);
//printf("main函数中a的地址为:%p\n", a);
//printf("Add函数中a指向的值为:%d\n", *a);
int* c = (int*)malloc(sizeof(int));
*c = (*a) + (*b);
return c;
}
int main() {
int a = 2;
int b = 4;
//printf("main函数中a的地址为:%p\n", &a);
int* ptr = Add(&a, &b);
printfHelloWorld();
printf("sum = %d", *ptr);
return 0;
}