欢迎光临
我们一直在努力

c语言学习笔记:函数与数组

函数传参与变量生命周期,C语言后半段的几个关键点

 

把函数和数组结合起来用之后,才算真正摸到C语言模块化编程的门。简单记一下这几块的核心,免得以后翻笔记。

 

一、函数和一维整型数组

 

数组传给函数的时候,传过去的不是整个数组,是首元素的地址。所以函数里改了数组元素,外面的数组也跟着变——这跟普通变量的值传递不一样。

 

c

void print_array(int a[], int len)

{

    // 这里 sizeof(a) 求的是指针大小,不是整个数组大小

}

 

几个要注意的点:

 

– 形参写  int a[] ,方括号里的常量写不写都行,编译器都当成指针处理

– 本质传的是首地址,所以必须单独把长度传进去

– 函数内部用数组跟外面一样,就是  sizeof(数组名)  不行了,退化成指针了

 

二、函数和一维字符数组

 

跟整型数组类似,但有个区别:字符数组存的是字符串,末尾有  '\\0'  结束标志,所以不用传长度,函数自己能找到结尾。

 

c

void print_str(char str[])

{

    // 靠 '\\0' 判断结束

}

 

当然, sizeof(str)  在函数里同样是指针大小,别搞错。

 

三、函数和二维整型数组

 

二维数组传参,列数不能省,行数可以省:

 

c

void print_2D_array(int a[][4], int hang)

{

    // 列数必须写死

}

 

为什么列数不能省?因为编译器得知道一行有多长,才能算  a[i][j]  的地址。行数可以传参数进去,列数不行。

 

函数里算列数: sizeof(a[0]) / sizeof(a[0][0]) ,行数算不了,得靠参数传。

 

四、函数和二维字符数组

 

二维字符数组就是存多个字符串的。传参跟二维整型数组一个道理,列数必须写:

 

c

void print_2DC_array(char str[][100], int hang)

{

}

 

每一行就是一个字符串,用  str[i]  就能访问第 i 个字符串。

 

五、变量的作用域和生命周期

 

这一块容易搞混,分开看就清楚了。

 

作用域(空间角度)——变量在哪能用

 

– 局部变量:定义在  {}  里面,出了  {}  就用不了

– 全局变量:定义在所有函数外面,到处都能用

 

同名的时候遵循就近原则,内层的会把外层的"遮住"。

 

生命周期(时间角度)——变量活多久

 

– 局部变量:进函数的时候开辟空间,出函数就回收,不初始化是随机值

– 全局变量:程序运行前就开辟,程序结束才回收,默认初始化为 0

– static 修饰的局部变量:作用域还是局部,但生命周期变成了全局的——函数退出了它还在,下次调用还能接着用

 

内存分布上,局部变量在栈区,全局变量和 static 变量在数据区(初始化的在 .data,没初始化的在 .bss)。

 

存储类型关键字

 

–  auto :默认的,局部变量都是 auto,一般不写

–  static :修饰局部变量延长生命周期;修饰全局变量或函数,限制只能在当前文件里用

–  register :建议编译器把变量放寄存器里,只是建议,不一定真放;寄存器变量不能取地址

–  extern :声明外部的全局变量或函数,告诉编译器这个东西在别的文件里定义了

 

函数传参、作用域、生命周期,把这几个概念理清楚,写代码的时候就不容易出莫名其妙的 bug 了。尤其是 static 和数组传参,初学的时候最容易踩坑。

赞(0)
未经允许不得转载:171主机测评 » c语言学习笔记:函数与数组
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址