C语言---指针变量作为函数参数

在C语言中,函数的参数不仅可以是整数、小数、字符等具体的数据,还可以是指向它们的指针。用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着函数的结束而被销毁。
像数组、字符串、动态分配的内存等都是一系列数据的集合,没有办法通过一个参数全部传入函数内部,只能传递它们的指针,在函数内部通过指针来影响这些数据集合。
有的时候,对于整数、小数、字符等基本类型数据的操作也必须要借助指针,一个典型的例子就是交换两个变量的值。
有些初学者可能会使用下面的方法来交换两个变量的值:

  1. #include <stdio.h>
  2. void swap(int a, int b){
  3. int temp; //临时变量
  4. temp = a;
  5. a = b;
  6. b = temp;
  7. }
  8. int main(){
  9. int a = 66, b = 99;
  10. swap(a, b);
  11. printf("a = %d, b = %d\n", a, b);
  12. return 0;
  13. }

运行结果:
a = 66, b = 99

从结果可以看出,a、b 的值并没有发生改变,交换失败。这是因为 swap() 函数内部的 a、b 和 main() 函数内部的 a、b 是不同的变量,占用不同的内存,它们除了名字一样,没有其他任何关系,swap() 交换的是它内部 a、b 的值,不会影响它外部(main() 内部) a、b 的值。

改用指针变量作参数后就很容易解决上面的问题:

  1. #include <stdio.h>
  2. void swap(int *p1, int *p2){
  3. int temp; //临时变量
  4. temp = *p1;
  5. *p1 = *p2;
  6. *p2 = temp;
  7. }
  8. int main(){
  9. int a = 66, b = 99;
  10. swap(&a, &b);
  11. printf("a = %d, b = %d\n", a, b);
  12. return 0;
  13. }

运行结果:
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(),用来查找数组中值最大的元素:

  1. #include <stdio.h>
  2. int max(int *intArr, int len){
  3. int i, maxValue = intArr[0]; //假设第0个元素是最大值
  4. for(i=1; i<len; i++){
  5. if(maxValue < intArr[i]){
  6. maxValue = intArr[i];
  7. }
  8. }
  9. return maxValue;
  10. }
  11. int main(){
  12. int nums[6], i;
  13. int len = sizeof(nums)/sizeof(int);
  14. //读取用户输入的数据并赋值给数组元素
  15. for(i=0; i<len; i++){
  16. scanf("%d", nums+i);
  17. }
  18. printf("Max value is %d!\n", max(nums, len));
  19. return 0;
  20. }

运行结果:
12 55 30 8 93 27
Max value is 93!

参数 intArr 仅仅是一个数组指针,在函数内部无法通过这个指针获得数组长度,必须将数组长度作为函数参数传递到函数内部。数组 nums 的每个元素都是整数,scanf() 在读取用户输入的整数时,要求给出存储它的内存的地址,nums+i就是第 i 个数组元素的地址。

用数组做函数参数时,参数也能够以“真正”的数组形式给出。例如对于上面的 max() 函数,它的参数可以写成下面的形式:

  1. int max(int intArr[6], int len){
  2. int i, maxValue = intArr[0]; //假设第0个元素是最大值
  3. for(i=1; i<len; i++){
  4. if(maxValue < intArr[i]){
  5. maxValue = intArr[i];
  6. }
  7. }
  8. return maxValue;
  9. }

int intArr[6]好像定义了一个拥有 6 个元素的数组,调用 max() 时可以将数组的所有元素“一股脑”传递进来。

读者也可以省略数组长度,把形参简写为下面的形式:

  1. int max(int intArr[], int len){
  2. int i, maxValue = intArr[0]; //假设第0个元素是最大值
  3. for(i=1; i<len; i++){
  4. if(maxValue < intArr[i]){
  5. maxValue = intArr[i];
  6. }
  7. }
  8. return maxValue;
  9. }

int intArr[]虽然定义了一个数组,但没有指定数组长度,好像可以接受任意长度的数组。
实际上这两种形式的数组定义都是假象,不管是int intArr[6]还是int intArr[]都不会创建一个数组出来,编译器也不会为它们分配内存,实际的数组是不存在的,它们最终还是会转换为int *intArr这样的指针。这就意味着,两种形式都不能将数组的所有元素“一股脑”传递进来,大家还得规规矩矩使用数组指针。
int intArr[6]这种形式只能说明函数期望用户传递的数组有 6 个元素,并不意味着数组只能有 6 个元素,真正传递的数组可以有少于或多于 6 个的元素。
需要强调的是,不管使用哪种方式传递数组,都不能在函数内部求得数组长度,因为 intArr 仅仅是一个指针,而不是真正的数组,所以必须要额外增加一个参数来传递数组长度。
C语言为什么不允许直接传递数组的所有元素,而必须传递数组指针呢?
参数的传递本质上是一次赋值的过程,赋值就是对内存进行拷贝。所谓内存拷贝,是指将一块内存上的数据复制到另一块内存上。
对于像 int、float、char 等基本类型的数据,它们占用的内存往往只有几个字节,对它们进行内存拷贝非常快速。而数组是一系列数据的集合,数据的数量没有限制,可能很少,也可能成千上万,对它们进行内存拷贝有可能是一个漫长的过程,会严重拖慢程序的效率,为了防止技艺不佳的程序员写出低效的代码,C语言没有从语法上支持数据集合的直接赋值。
除了C语言,C++、Java、Python 等其它语言也禁止对大块内存进行拷贝,在底层都使用类似指针的方式来实现。

原文地址:https://www.cnblogs.com/crazyprince/p/10344933.html

时间: 2024-10-10 01:00:54

C语言---指针变量作为函数参数的相关文章

C语言指针变量作为函数参数

0x01 指针变量作为函数参数的作用是:将一个变量的地址传送到另一个函数中. 0x02 简单的例子:虽然都能实现功能,但意义不同. 正确的写法: 1 #include <stdio.h> 2 3 void shuchu(int *p) 4 { 5 printf("%d\n", *p); 6 } 7 8 int main() 9 { 10 int a; 11 int *pa; 12 scanf("%d", &a); 13 pa = &a;

C言语指针变量作为函数参数

在C言语中,函数的参数不只可所以整数.小数.字符等详细的数据,还可所以指向它们的指针.用指针变量作函数参数可以将函数内部的地址传递到函数外部,使得在函数外部可以操作函数内部的数据,而且这些数据不会跟着函数的完毕而被烧毁.像数组.字符串.静态分派的内存等多是一系列数据的聚集,没有方法经过一个参数全体传入函数外部,只能传递它们的指针,在函数外部经过指针来影响这些数据聚集.有的时分,关于整数.小数.字符等根本类型数据的操作也必需要借助指针,一个典型的例子就是交流两个变量的值.有些初学者能够会运用下面的

编程题:指针变量作函数参数,将两个整数按由大到小的顺序输出。

分析:通过指针变量作函数参数,无需返回值和全局变量,主调函数就可以使用被调用函数改变的值. #include<stdio.h> void swap(int *p1,int *p2) { int p; p=*p1; *p1=*p2; *p2=p; } void main() { int a=3,b=4; int *ptr1,*ptr2; ptr1=&a;ptr2=&b; if(a<b) swap(ptr1,ptr2); printf("%d,%d\n",

[C++程序设计]用指针变量作函数参数接收数组地址

1 #include <iostream> 2 using namespace std; 3 4 void select_sort(int *p, int n) 5 { 6 int i, j, k; 7 for(i = 0; i < n - 1; i++) 8 { 9 for(j = i + 1; j < n; j++) 10 { 11 if(p[i] > p[j]) 12 { 13 k = p[i]; 14 p[i] = p[j]; 15 p[j] = k; 16 } 17

C语言 结构指针变量作函数参数和链表基础

结构体变量作为函数参数(传递整个结构体): 指向结构体变量的指针作为实参(传递结构体的地址): 数据结构之链表:   原文地址:https://www.cnblogs.com/souhaite/p/10960457.html

指针变量作为函数参数(1)

普通函数参数 下面程序试图改变main函数中a和b的值 #include<stdio.h> void fun(int x,int y) { int c; c=a; a=b; b=c; } int main() { int a=1,b=2; fun(a,b); printf("a=%d b=%d\n",a,b); return 0; } 函数参数传递分析: 实参: &a 28ff18 a  1 &b 28ff14 b  2 在将实参传递给形参的时候,编译器将实

(struct)结构体变量作为函数参数调用的方法小结

结构体变量.结构指针变量.结构数组作为函数的参数应用实例分析 struct stud { long int num; float score; }; /*结构体变量作为函数的参数,修改之后的成员值不能返回到主调函数*/ void funvr(struct stud t) { t.num=2000101; t.score=71.0; } /*结构体数组作为函数的参数,修改后的元素的成员值能返回到主调函数*/ void funar(struct stud t[]) //void funar(stru

[C++程序设计]用函数指针变量调用函数

指针变量也可以指向一个函数.一个函数在编译时被分配给一个入口地址.这个函数入口地址就称为函数的指针.可以用一个指针变量指向函数,然后通过该指针变量调用此函数 1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int max(int,int); 7 int (*p)(int,int); 8 p = max; 9 int m, a, b; 10 cin >> a >> b; 11 m = p(

C语言--- 高级指针2(结构体指针,数组作为函数参数)

一.结构体指针 1. 什么是结构体指针?指向结构体变量的指针     结构体:     typedef  struct stu{                          char name[20];                          char sex;                          int age;                    }Student;     Student stu1 = {"zhangsan",'m',23};