C语言函数重制版(内含指针串讲)

#如果指针有不懂的可以先去看一下我的指针讲解#

目录

函数传参

函数的概念

函数的语法形式

传参:

参数与指针串讲     

return

数组名作为函数参数

一维数组函数传参

扫描二维码关注公众号,回复: 17520218 查看本文章

二维数组函数传参

多个文件函数的声明和定义

  作用域和生命周期

static

static修饰局部变量   

static修饰全局变量 

static修饰函数

使用建议

extern

内存分区        



函数传参

         当实参传递给形参的时候,形参是有自己的内存地址的,形参是实参的一份临时拷贝,对形参修改不会影响实参。

        通过上面的这个例子不难看出,函数里面的 x 确实被改变了,但是函数外 main 函数里面的 a 却依旧是 3,我们如果想利用函数来修改 a(又名实参),可通过传地址以及解引用来实现修改,如下。

通过地址来操作,我们相当于直接使用了 a,而没有对 a 进行拷贝。所以可以远程修改 a 里面存放的值。

_____________________________________________________________________________

函数的概念

        C语言中的函数就是一个完成某项特定的人物的一段代码。

        C语言的程序其实是有无数个小的函数组合而成的,也可以说:一个大的计算任务可以分解成若干较小的函数(对应较小的任务)完成。

        每一次使用库函数都要包含相应的头文件。

函数的语法形式

        函数返回类型+函数名+(形式参数)大括号里是函数体(需要自己设计),构成函数。

        如下图我们可以看见,我们的参数 和返回类型都可以为空,就是我不需要返回值,或者我不需要参数,

        如第一个函数,我只需要你给我修改一下值就行了,不需要返回值,或者我调用某个函数的目的就是打印一句话,我就不需要返回值,不需要我就不写。

        第二个函数,我的参数为空,我调用这个函数的目的就是你给我返回一个1就行了。

        甚至返回类型和参数我都可以不要。但是这里有一点需要说的是,参数可以什么都不写,但是返回类型,如果不需要就写 void ,不能不写。

传参:

        传的什么类型的参数,就需要在函数括号里定义相同类型的参数来接受。

        传的地址我就通过一个指针来接收,传的整形变量我就通过定义一个整形变量接收

参数与指针串讲     

        1、只有在传递实参的时候,形参才会向内存申请空间,没有传参的话就不会提出申请。

        2、形参和实参的地址不一样,意味着形参有形参的空间实参有实参的空间。

        如图我们可以看见,b 与 y 的地址不一样,地址一样也就意味着不属于同一块空间。

而我们 a 的地址和 x 里面存放的地址是一样的,那么我们解引用 x 就相当于使用同一块空间了,所以可以改变 a里面的值。

     

          提一嘴,x也有自己的地址,上面说了一个地址代表一块空间,此时如果想要使用 x,那么只能给他换一个地址。因为 x 这一块地址的属性是 int*,所以只能放该属性的内容。而我们解引用 x,相当于解引用 x 里面的地址,就可以使用这一个地址所代表的空间了。这块地址的属性就是 int(一个int类型有4个地址我们只是看见了第一而已)。我们可以给这一块空间赋值上 Int类型的的参数。

        3、函数返回的值是暂时放在寄存器里的,回到主函数时接受返回值。

        4、寄存器是集成在CPU上的,没有地址,内存才有地址。

        5、形参只能在函数内部使用,除了函数就回收了。出了函数空间就没了。

return

        return 后面可以是数值也可以是表达式,如果是表达式则先执行表达式,再返回表达式的结果。x大于y吗?大于返回x,否则返回 y。

        在函数里return后面可以不写,反空值用void接受,也可以不写return。

        return 返回后函数结束,如果后面还有代码则不执行。可用作某种条件成立时提前结束函数。

        如果返回的值,与接收类型不一样,则会强制转换为返回类型(函数名前面的类型)。

        如果函数里面有if和分支,则要保证每种情况都有return返回,否则就会出错。

数组名作为函数参数

        主函数里的数组传参时,直接传数组名(多维数组和指针那儿会有点区别)就行。接受时也用类型+数组接收,如果你定义的是一个数组来接收,那么也是拷贝一份,如果是指针,就可以操作原数组。

        

        1、函数的形式参数要和函数的实参个数匹配

        2、函数的实参是数组时,形参也是可以写成数组形式的(也可以用指针接收)

一维数组函数传参

        3、形参如果是一维数组,数组的大小可以省略不写,

如果给了大小也是同一个数组也能操作主函数里的数组

直接用指针接收或者,用上图的形式接收,都可以用下标访问和解引用来实现访问。

注:解引用操作不能先解引用arr,先解引用就不能加 i 了,先解引用访问空间得到一个元素或者这块空间(被赋值就是使用空间,其他时候表元素。),所以左边就变成了常量

二维数组函数传参

      数组名传参,表示首元素地址,而二维数组的首元素是一个一维数组。

        可以仅用一个一维数组接收,甚至你还越界访问,因为二维数组的地址也是连续存放的所以,你只要不超整个二维数组的大小就行,那个4也能改 最后:可以这么写,但你不要这么写

        感觉没什么好说的了,可以直接去看我的指针博客,里面的二维数组章节

        5、数组传参,形参是不会创建新的数组的

        6、形参操作的数组和实参的数组时同一个

        函数里面不能再定义一个其他的函数,但可以使用其他函数。

多个文件函数的声明和定义

        在头文件.h里面放:函数的声明和类型的声明。

        源文件里放函数的定义。

使用时:#include"( 头文件名 ).h",里面有函数的声明,把函数写在另一个.c文件里,主函数里调用就行。

  作用域和生命周期

1、哪里能使用哪里就是作用域

2、局部变量的作用域是变量所在的局部范围(也就是花括号的内的范围),你只能在括号范围内才能使用

3、全局变量的作用域是整个工程(多个文件应该也行)

4、局部变量在出了生命周期(出了花括号就不能使用了),就会销毁把申请的空间还回去。

5、全局变量只有程序运行结束才会销毁。

static

static修饰局部变量   

            出了生命周期不销毁 。 我们调用两次都是 0 ,那么如果加上一个 static 修饰呢?

 

加了static修饰之后,函数结束时,a变量里面的值被保存了下来。

static修饰全局变量 

       只能在本文件内使用, 失去了外部链接属性(其他源文件不得使用)。

这个 a 被声明后本来是可以使用的但如果加上一个 static修饰呢?

迎接你的将是无法解析的外部符号,你不能用我的 a 了。

static修饰函数

        也只能在本文件使用,失去了外部链接属性。和上面的全局变量一样

使用建议

        在变量出了函数之后,我们还想保留值,就可以用static修饰     

多个文件编译时,每个源文件都是单独编译的,

extern

        声明外部符号。

在声明函数时,记得带上参数。

内存分区        

        栈区:存放局部变量和函数的参数。

        堆区:动态内存分配。malloc , calloc , realloc , free.

        静态区:全局变量和静态变量(程序不结束变量不销毁),只有程序结束,变量才会销毁,内存才会回收,但是作用域不变。

猜你喜欢

转载自blog.csdn.net/liu_qiang_dage/article/details/142819552