印度小哥讲解的指针, 真的很好, 这里附上链接:
https://www.bilibili.com/video/BV1bo4y1Z7xf/?spm_id_from=333.999.0.0
1. 数组作为函数参数
1.1 数组作为函数参数的一个经典问题
为什么不将对应的 size
传进函数中, 数组就无法执行.
// 注意:这里有一个需要关注的地方:在64位的操作系统下, 一个指针的大小是8个字节, 但是在86位的操作系统下, 一个指针是4个字节.
// 所以要是最后的结果是“3”, 那就应该是操作系统的原因, 修改为64位的操作系统就行.
int sumOfArr(int arr[]) {
int sum = 0;
int size = sizeof(arr) / sizeof(arr[0]);
printf("sumOfArr函数中的 arr大小 = %d, arr[0]大小 = %d\n", sizeof(arr), sizeof(arr[0]));
for (int i = 0; i < size; i++) {
//sum += arr[i];
sum += *(arr + i);
}
return sum;
}
int main() {
int arr[] = { 1, 2, 3, 4, 5 };
printf("main函数中的 arr大小 = %d, arr[0]大小 = %d\n", sizeof(arr), sizeof(arr[0]));
int total = sumOfArr(arr);
printf("%d", total);
return 0;
}
1.2 用内存结构解释这个问题
在图中的 main函数的栈帧
中, 有一个数组, 但是在 sumOfArr函数的栈帧
创建的一个 int arr[]
实际上是一个 int类型的指针(int* arr)
, 只是指向了 main函数的栈帧
中的数组中的 基地址
. 所以 sizeof(arr)
的值是一个 指针
的大小.
因为一个数组有可能是很大的, 若是都进行全部的复制, 这样有点太浪费空间了.
1.2.1 指针在数组上的移动 (数组作为参数)
从代码中也能看出来, 指针的移动还是从 arr[0]
开始的, 接下来指向 main函数栈帧
中的 数组
.
void Double(int* arr, int size) {
for (int i = 0; i < size; i++) {
arr[i] = 2 * arr[i];
}
}
int main() {
int arr[] = { 1, 2, 3, 4, 5 };
int size = sizeof(arr) / sizeof(arr[0]);
Double(arr, size);
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
return 0;
}