在C语言中,函数参数不仅可以是整数、小数、字符等具体数据,还可以是指向它们的指针。 使用指针变量作为函数参数,可以将函数外部的地址传递到函数内部,这样就可以在函数内部操作函数外部的数据,并且这些数据在函数结束时不会被破坏。
数组、字符串、动态分配的内存等都是一系列数据的集合。 没有办法通过一个参数将它们全部传递到函数中。 它们只能传递它们的指针,而这些数据集合是通过函数内部的指针来影响的。
有时,对整数、小数、字符等基本类型数据的操作也必须使用指针。 一个典型的例子就是交换两个变量的值。
有些初学者可能会使用下面的方法来交换两个变量的值:
#include
void swap(int a, int b){
int temp; //临时变量
temp = a;
a = b;
b = temp;
}
int main(){
int a = 66, b = 99;
swap(a, b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
运行结果:
a = 66,b = 99
从结果可以看出a和b的值没有改变,交换失败。 这是因为swap()函数中的a和b与main()函数中的a和b是不同的变量,占用不同的内存。 除了同名之外,他们没有其他关系。 swap()交换的是它内部的a和b的值,不会影响它外部(main()内部)a和b的值。
使用指针变量作为参数可以轻松解决上述问题:
#include
void swap(int *p1, int *p2){
int temp; //临时变量
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main(){
int a = 66, b = 99;
swap(&a, &b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
运行结果:
a = 99,b = 66
调用swap()函数时,将变量a和b的地址分别赋值给p1和p2,这样*p1和*p2就代表变量a和b本身。 交换*p1和*p2的值就意味着交换a和b。 价值。 虽然函数运行后p1和p2会被销毁,但它对外部a和b的影响是“持久的”,不会在函数结束时“恢复”。
需要注意的是,临时变量temp起着特别重要的作用,因为执行*p1 = *p2;后a的值会被b的值覆盖。 陈述。 如果不先保存a的值,后面就找不到了。
使用数组作为函数参数
数组是一系列数据的集合,不能通过参数一次性传入函数中。 如果要在函数内部操作数组,则必须传递数组指针。 以下示例定义了一个函数 max() 来查找数组中具有最大值的元素:
#include
int max(int *intArr, int len){
int i, maxValue = intArr[0]; //假设第0个元素是最大值
for(i=1; i<len; i++){
if(maxValue < intArr[i]){
maxValue = intArr[i];
}
}
return maxValue;
}
int main(){
int nums[6], i, maxValue;
int len = sizeof(nums)/sizeof(int);
//读取用户输入的数据并赋值给数组元素
for(i=0; i<len; i++){
scanf("%d", nums+i);
}
printf("Max value is %d!\n", max(nums, len));
return 0;
}
运行结果:
12 55 30 8 93 27↙
最大值为 93!
参数只是一个数组指针。 函数内部无法通过this指针获取数组长度。 数组长度必须作为函数参数传递给函数。 数组 nums 的每个元素都是一个整数。 当scanf()读取用户输入的整数时,它需要存储它的内存地址。 nums+i 是第 i 个数组元素的地址。
当使用数组作为函数参数时,参数也可以以“真实”数组的形式给出。 例如,对于上面的 max() 函数,其参数可以写成以下形式:
int max(int intArr[6], int len){
int i, maxValue = intArr[0]; //假设第0个元素是最大值
for(i=1; i<len; i++){
if(maxValue < intArr[i]){
maxValue = intArr[i];
}
}
return maxValue;
}
int[6] 似乎定义了一个有 6 个元素的数组。 调用 max() 时,可以“一次全部”传入数组的所有元素。
读者还可以省略数组长度,将形参缩写如下:
int max(int intArr[], int len){
int i, maxValue = intArr[0]; //假设第0个元素是最大值
for(i=1; i<len; i++){
if(maxValue < intArr[i]){
maxValue = intArr[i];
}
}
return maxValue;
}
int[]虽然定义了一个数组,但是并没有指定数组长度。 看起来它可以接受任意长度的数组。
事实上,这两种形式的数组定义都是错觉。 int[6]和int[]都不会创建数组,编译器也不会为它们分配内存。 实际的数组不存在。 它们最终会被转换为像 int * 这样的指针。 这意味着这两种形式都不能“一次”传入数组的所有元素,每个人都必须正确使用数组指针。
int[6] 形式仅表明该函数期望用户传递的数组有 6 个元素。 这并不意味着数组只能有 6 个元素。 实际传递的数组可以少于或多于 6 个元素。
需要强调的是,无论用哪种方法传递数组,函数内部都无法获取数组长度,因为它只是一个指针,并不是真正的数组,所以必须添加一个额外的参数来传递数组长度。
为什么C语言不允许直接传递数组的所有元素,而必须传递数组指针?
参数的传递本质上是一个赋值过程,赋值就意味着复制内存。 所谓内存复制是指将一个内存上的数据复制到另一个内存上。
对于int、float、char等基本类型的数据来说,它们往往只占用几个字节的内存,而且内存复制它们的速度非常快。 数组是一系列数据的集合。 数据数量没有限制。 可能是几个或数千个。 将它们复制到内存中可能是一个漫长的过程,并且会严重降低程序的效率。 为了防止技术错误,贫穷的程序员编写低效的代码,并且C语言在语法上不支持数据集合的直接赋值。