参数和指针|学习笔记

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

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

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


参数和指针


参数和指针

 

简介:

一、参数和返回值

二、形参和实参

三、传值和传址

四、传数组

五、可变参数

 

一、参数和返回值

1.参数的用法和作用

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

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

2. 类型名

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

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

 

二、形参和实参

1.定义

形参:形式参数

实参;实际参数

2.举例

#include <stdio.h>

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 <stdio.h>

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 <std1o.h>

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 <stdio . h>

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 <stdio . h>

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 <stdio . h>

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 <stdarg.h>

一个类型:

va_list-定义字符指针的类型

三个宏:

va_start-对字符指针进行计算

va_arg

va_end

其中,va即variable-argument的缩写

2.示例

[fishc@bogon sle29]$ gcc test4.c

#include <stdio . h>

#include <stdarg.h>

 

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 <n;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]$

相关文章
|
8天前
|
存储 Go
Go: struct 结构体类型和指针【学习笔记记录】
本文是Go语言中struct结构体类型和指针的学习笔记,包括结构体的定义、成员访问、使用匿名字段,以及指针变量的声明使用、指针数组定义使用和函数传参修改值的方法。
|
2月前
|
程序员 C语言
指针在函数参数和返回值中的使用
指针在函数参数和返回值中的使用
33 9
|
3月前
|
运维
系统日志使用问题之如何防止在打印参数时遇到NPE(空指针异常)
系统日志使用问题之如何防止在打印参数时遇到NPE(空指针异常)
|
2月前
|
存储 C++
c++学习笔记06 指针
C++指针的详细学习笔记06,涵盖了指针的定义、使用、内存占用、空指针和野指针的概念,以及指针与数组、函数的关系和使用技巧。
30 0
|
5月前
|
存储 C语言
字符指针作为函数参数
字符指针作为函数参数
49 2
|
4月前
|
编译器 vr&ar C语言
C primer plus 学习笔记 第10章 数组和指针
C primer plus 学习笔记 第10章 数组和指针
|
5月前
|
存储 C语言
指针变量作为函数参数
指针变量作为函数参数
28 0
|
5月前
|
算法 C语言
使用指向函数的指针作为函数参数
使用指向函数的指针作为函数参数
26 0
|
5月前
|
C++
结构体变量与结构体变量指针作为函数参数
结构体变量与结构体变量指针作为函数参数
27 0
|
5月前
|
程序员 C语言
使用指针变量作为函数参数的C语言程序实例
使用指针变量作为函数参数的C语言程序实例
56 0