目录
原码如下:
/*-----------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
void populate_array(int *array, size_t arraySize, int(*getNextValue)(void))
{
for (size_t i = 0; i<arraySize; i++)
array[i] = getNextValue();
}
//获取随机值
int getNextRandomValue(void)
{
return rand();
}
int main(void)
{
int myarray[10];
/*getNextRandomValue 不能加括号,否则无法编译,因为加上括号之后相当于传入此参数时传入了 int,而不是函数指针*/populate_array(myarray, 10, getNextRandomValue);
for (int i = 0; i < 10; i++)
{
printf("%d ", myarray[i]);
}
printf("\n");
return 0;
}
/*-----------------------------------------------------------------------*/
1. 问题描述
在`populate_array`函数中,第一个参数是指针`int *array`,为什么在函数体里可以像数组一样使用`array[i]`?
2. 问题解析
在C语言中,数组和指针有密切的关系。以下是对这一现象的解释:
1. 数组名是指向数组首元素的指针:
- 当你定义一个数组时,例如`int myarray[10];`,`myarray`实际上是一个指向数组第一个元素的指针,即`myarray`等价于`&myarray[0]`。
- 因此,当你将数组名`myarray`传递给函数时,实际上传递的是数组首元素的地址。
2. 指针可以像数组一样使用下标访问:
- 在C语言中,指针和数组的访问方式是等价的。对于指针`int *array`,`array[i]`等价于`*(array + i)`。
- 这是因为数组在内存中是连续存储的,通过指针的偏移量(`i`)可以访问数组中的任意元素。
3. 函数参数中的数组会被隐式转换为指针:
- 当数组作为函数参数时,C语言会自动将其转换为指向数组首元素的指针。例如,`void populate_array(int array[], size_t arraySize, ...)`和`void populate_array(int *array, size_t arraySize, ...)`是等价的。
3. 代码解释
以下是对代码的详细解释:
/*-----------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
// populate_array 函数:用 getNextValue 函数生成的值填充数组
void populate_array(int *array, size_t arraySize, int(*getNextValue)(void))
{
for (size_t i = 0; i < arraySize; i++)
array[i] = getNextValue(); // 通过指针访问数组元素
}
// getNextRandomValue 函数:返回一个随机值
int getNextRandomValue(void)
{
return rand(); // 使用 rand() 生成随机数
}
int main(void)
{
int myarray[10]; // 定义一个长度为 10 的数组
// 调用 populate_array 函数,填充数组
populate_array(myarray, 10, getNextRandomValue);
// 打印数组内容
for (int i = 0; i < 10; i++)
{
printf("%d ", myarray[i]);
}
printf("\n");
return 0;
}
/*-----------------------------------------------------------------------*/
关键点:
1. `populate_array`函数:
- 第一个参数`int *array`是一个指针,指向数组的首元素。
- 在函数体内,`array[i]`通过指针访问数组的第`i`个元素,等价于`*(array + i)`。
2. `getNextRandomValue`函数:
- 这是一个回调函数,用于生成随机值。
- 在`populate_array`中,通过`getNextValue()`调用该函数。
3. `main`函数:
- 定义了一个长度为10的数组`myarray`。
- 调用`populate_array`函数,将`myarray`的地址传递给`populate_array`。
- 打印填充后的数组内容。
4. 实例增加理解
为了更好地理解指针和数组的关系,可以通过以下实例加深理解:
示例1:指针和数组的等价性
/*-----------------------------------------------------------------------*/
#include <stdio.h>
int main(void)
{
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // ptr 指向数组的首元素
// 通过数组下标访问
printf("arr[2] = %d\n", arr[2]); // 输出: 30
// 通过指针下标访问
printf("ptr[2] = %d\n", ptr[2]); // 输出: 30
// 通过指针算术访问
printf("*(ptr + 2) = %d\n", *(ptr + 2)); // 输出: 30
return 0;
}
/*-----------------------------------------------------------------------*/
示例2:函数参数中的数组和指针
/*-----------------------------------------------------------------------*/
#include <stdio.h>
// 函数参数中的数组会被隐式转换为指针
void printArray(int *arr, size_t size)
{
for (size_t i = 0; i < size; i++)
{
printf("%d ", arr[i]); // 通过指针访问数组元素
}
printf("\n");
}
int main(void)
{
int arr[5] = {1, 2, 3, 4, 5};
printArray(arr, 5); // 传递数组名(指针)
return 0;
}
/*-----------------------------------------------------------------------*/
总结
- 在C语言中,数组名是指向数组首元素的指针。
- 指针可以通过下标访问数组元素,例如`array[i]`等价于`*(array + i)`。
- 函数参数中的数组会被隐式转换为指针,因此`int *array`和`int array[]`是等价的。
- 通过理解指针和数组的关系,可以更灵活地操作数组和内存。