参数和指针|学习笔记

简介: 快速学习参数和指针

开发者学堂课程【你的第一门 C 语言课参数和指针】学习笔记,与课程紧密联系,让用户快速学习知识

课程地址:https://developer.aliyun.com/learning/course/444/detail/5495


参数和指针


简介:

一、参数和返回值

二、形参和实参

三、传值和传址

四、传数组

五、可变参数

 

一、参数和返回值

1.参数的用法和作用

函数是一种封装的方法。函数的设计遵从一个函数仅实现一个功能的原则,便可化繁为简,将复杂的程序拆解开,变成一个个独立的功能。每个功能使用单个函数实现。

函数定义时通过参数列表以指定函数的数量和类型,前者使得后者更加灵活。传入的参数使得函数拥有更为丰富的功能。同时,函数应支持个性化定制

2. 类型名

函数实现功能通常需要反馈结果,但实际操作中并不一定出现,故需要设定一个返回值以观察函数调用是否成功,或者出现了何种问题。若函数的确不需要返回值,则可以使用 void 以表示不返回。

定义函数时,已经确定了参数的数量和类型,但参数数量是可变的。

 

二、形参和实参

1.定义

形参:形式参数

实参;实际参数

2.举例

#include

int sum(int, int);

int sum(int x,int y)

{

return (x + y);

}

int main()

{

sum(3, 5);

return 0 ;

}

其中,int x,int y 为形参。其仅作为占位符,并无实际的数值。而在函数被调用期间,传与其一个实际的数值,例如3, 5,此为实际数值,被称为实参。

形参与实参均用于数据传输,当函数发生调用时实参的数值将传递给形参,此种传输具有单向性,即不能讲形参的值传输给实参。形参变量定义时仅作为一个占位符,提示需要留存变量并保留空间,并无实际数据的传输,数值仍为随机。只有在函数调用时,数值的位置才会真正生成空间、分配内存。而当函数调用结束后,其又会立刻释放内存。故,形参变量仅在函数内部有效。

 

三、传值和传址

指针是一个变量,可以通过参数传递给函数。

1.引进指针参数的实际意义

(1).不使用指针的示例:

#include

void swap(int x,int y);

void swap(int x,int y)

{

int temp

printf(“In sawp,互换前:x=%d,y=%d\n”,x,y);

temp=x  

x=y

y=temp  /*两数交换所需要的中间值*/

printf(“In sawp,互换后:x=%d,y=%d\n”,x,y);

}

int main( )

{

int x=3,y=5;

printf(“In main,互换前:x=%d,y=%d\n”,x,y);

swap(x,y); /*swap:互相交换的含义*/

printf(“In main,互换后:x=%d,y=%d\n”,x,y);

return0;

}

得到结果:

[fishc@bogon sle29]$ gcc testl.c && . /a . out

in main,互换前:x=3,y=3;

in swap,互换前:x=3,y=5;

in swap,互换前:x=5,y=3;

in main,互换前:x=3,y=5;

fishc@bogon sle29] $   //结果与预料相同

(2).使用指针的示例:

[fishc@bogon sle29] $ cp test1.c test2.c

[fishc@bogon sle29] $ vi test2.c

#include

void swap(int *x,int *y);  //指针x,y存放的是数值,对其都要进行解引用

void swap(int *x,int *y)

{

int temp

printf(“In sawp,互换前:x=%d,y=%d\n”,*x,*y);

temp=*x  

*x=*y

*y=temp

printf(“In sawp,互换后:x=%d,y=%d\n”,*x,*y);

}

int main( )

{

int x=3,y=5;

printf(“In main,互换前:x=%d,y=%d\n”,x,y);

swap(&x,&y); //指针中存放的必须为地址

printf(“In main,互换后:x=%d,y=%d\n”,x,y);

return0;

}y

得到结果:

[fishc@bogon sle29]$ gcc test2.c && . /a . out

in main,互换前:x=3,y=3;

in swap,互换前:x=3,y=5;

in swap,互换前:x=5,y=3;

in main,互换前:x=5,y=3;

fishc@bogon sle29] $

(3).结论

当不使用指针时,函数内部无法改变实参的值,即内部 (swap) 互换之后,在 main 中的值仍未改变。

由于 C 语言中每个函数都有独立的作用域,即每个函数的内部都是互相独立的,他们的作用旨在函数内部生效,不同函数之间不能直接访问对方的变量。例如 main和 swap 两个作用域中的x,y并不冲突,是不同的两组变量。

2.使用指针能改变的原因

指针中存放的是别人的地址,例如经 main 函数中的 x,y 两个地址传递给形参,则两个形参函数 x,y 即是对两个变量 x,y 的引用。引用后相当于将其地址搬到另一处,直接进行互换。

实现了传值和传址的根本区别。


四、传数组

1.示例一

[fishc@bogon sle29]$ gcc test3.c

#include

void get_array(int a[10]); //array:数组

void get_array(int a[10])

{

int i;

for (i=0;i<10;i++)

{

printf(“a[%d] = %d\n”,i,a[i]);

}

}

int main()

{

int a[10]={1,2,3,4,5,6,7,8,9,0};

get_arrayp{a}

return 0 ;

}  

查看打印结果:

[fishc@bogon sle29]$ gcc test3.c && ./a.out

a[0] = 1

a[1] = 2

a[2] = 3

a[3] = 4

a[4] = 5

a[5] = 6

a[6] = 7

a[7] = 8

a[8] = 9

a[9] = 0

[fishc@bogon s1e29]$

在此基础上修改代码:

#include

void get_array(int a[10]);

void get_array(int a[10])

{

int i;

a[5] = 520;

for (i=0;i<10;i++)

{

printf(“a[%d] = %d\n”,i,a[i]);

}

}

int main()

{

int a[10]={1,2,3,4,5,6,7,8,9,0};

int i;

get_array(a);

printf(*在main函数中再打印一次...\n*);

for (i=0;i<10;i++)

{

printf(“a[%d] = %d\n”,i,a[i]);  

}

return 0 ;

}

若在调用时将整个数组传递进形参中,则两方的 a 同样是独立开的。此情况下的变量将不会被互相修改到。但实际情况如下:

[fishc@bogon sle29]$ gcc test3.c && ./a.out

a[0] = 1

a[1] = 2

a[2] = 3

a[3] = 4

a[4] = 5

a[5] = 520

a[6] = 7

a[7] = 8

a[8] = 9

a[9] = 0

在main函数里边再打印一次......

a[0] = 1

a[1] = 2

a[2] = 3

a[3] = 4

a[4] = 5

a[5] = 520

a[6] = 7

a[7] = 8

a[8] = 9

a[9] = 0

[fishc@bogon s1e29]$

此时 fishc 和 main 数组的函数都被改动,说明并不存在将整个数组作为参数传递的方式。接受的仅是地址本身。

2.示例二

[fishc@bogon sle29]$ gcc test4.c

#include

void get_array(int a[10]); //由于并不是将一个数组传递给过来,此处仅作为验证进行

void get_array(int a[10])

{

printf(“sizeof b: %d\n”,sizeof(b));

}

int main()

{

int a[10] = {1,2,3,4,5,6,7,8,9,0}

printf(“sizeof a: %d\n”,sizeof(a));

查看结果:

[fishc@bogon sle29]$ gcc test4.c && ./a.out

sizeof a:40  //a是41个元素,每一个整型变量在变异系统中占4个字节,总量为10x4=40字节

sizeof b:4 //仅作为地址,故只占有一个地址应有的尺寸,即4个字节

[fishc@bogon sle29]$

 

五、可变参数

1.定义

可变参数的实现需要包含头文件,即 stdarg.h,头文件中需要四个元素

#include

一个类型:

va_list-定义字符指针的类型

三个宏:

va_start-对字符指针进行计算

va_arg

va_end

其中,va即variable-argument的缩写

2.示例

[fishc@bogon sle29]$ gcc test4.c

#include

#include

int sum(int n...)  //...表示数目不确定

int sum(int n...)

{

int i,sum = 0;

va_list vap;  //定义参数列表

va_start(vap,n);   //传入宏va_start

for (i = 0;i

{

sum +=va_arg(vap,int);  //利用va_arg获取每一个参数的值、类型

}

va_end(vap); //va_end关闭参数列表

return sum;

}

int main()

{

int result;    //接收返回的结果

result = sum(3,1,2,3);

printf(“result1 =%d\n”,result);

result = sum(53,1,2,3,4,5);

printf(“result2=%d\n”,result);

result = sum(6,3,-1,-2,4,99,100);

printf(“result3=%d\n”,result);

return 0;

}

查看结果:

[fishc@bogon sle29]$ gcc test5.c && ./a.out

result1 = 6

result2 = 15

result3 = 203

[fishc@bogon sle29]$

相关文章
|
2月前
|
存储 C语言 C++
如何通过指针作为函数参数来实现函数的返回多个值
在C语言中,可以通过将指针作为函数参数来实现函数返回多个值。调用函数时,传递变量的地址,函数内部通过修改指针所指向的内存来改变原变量的值,从而实现多值返回。
|
6月前
|
测试技术 C++ 开发者
智慧指针是什么以及具体用法
智慧指针是什么以及具体用法
43 2
|
7月前
|
算法 C语言
使用指向函数的指针作为函数参数
使用指向函数的指针作为函数参数
36 0
|
7月前
指向结构体类型数据的指针
指向结构体类型数据的指针。
45 3
|
存储 C语言 C++
【指针的进阶(1)】指针的类型、数组传参和指针传参
【指针的进阶(1)】指针的类型、数组传参和指针传参
69 0
|
程序员 C语言 内存技术
指针的那些用法
什么是指针? 从根本上看,指针是一个值为内存地址的变量。正如char类型变量的值是字符,int类型变量的值是整数,指针变量的值是地址。 因为计算机或者嵌入式设备的硬件指令非常依赖地址,指针在某种程度上把程序员想要表达的指令以更接近机器的方式表达,因此,使用指针的程序更有效率。尤其是指针能够有效地处理数组,而数组表示法其实是在变相的使用指针,比如:数组名是数组首元素的地址。
120 0
指针的那些用法
|
机器学习/深度学习 程序员 C语言
传递结构体变量和结构体指针|学习笔记
快速学习传递结构体变量和结构体指针
176 0
传递结构体变量和结构体指针|学习笔记
指针(四)- 函数指针和回调函数
指针(四)- 函数指针和回调函数
|
C语言
传递指针给函数
传递指针给函数
61 0
|
C语言
从函数返回指针
从函数返回指针
76 0