C语言函数
当开始运行f1时,需要调用f1,而为了防止调用函数f1后无法回到main函数中,需要把main的地址保存下来,即入栈,所以此时在栈的最底层则是main的位置,此过程也被称为保护现场,而同理,f1和f2也接连入栈,于是在出栈时,顺序便是f2,f1,main,此过程也被称为恢复现场。综上,在c语言运行之前,必须开辟出来栈的空间,即栈区。为保证函数调用的正常运行,计算器会开辟新空间,记录调用前函数的位置
函数的递归
简而言之,函数的递归就是自己用自己(如果你了解科赫雪花的迭代或许能更好理解)。
以求1加到100为例。
#include <stdio.h>
int sum(int n)
{
if(n == 1)
return 1;
else
{
return sum(n - 1) + n;
}
}
int main()
{
printf("%d\n", sum(100));
}
该函数sum()便反复调用自身
函数调用的深入理解
数据结构——栈
为保证函数调用的正常运行,计算机会开辟新空间,记录调用前函数的位置,与缓存区空间的队列先进先出的特点不同,其特点为先进后出,即入栈和出栈。
以如下函数为例

当开始运行f1时,需要调用f1,而为了防止调用函数f1后无法回到main函数中,需要把main的地址保存下来,即入栈,所以此时在栈的最底层则是main的位置,此过程也被称为保护现场,而同理,f1和f2也接连入栈,于是在出栈时,顺序便是f2,f1,main,此过程也被称为恢复现场。Linux系统栈区内存大小为8G,Windows为1G
综上,在c语言运行之前,必须开辟出来栈的空间,即栈区。其实栈区内不光保存了返回函数的地址,局部变量,包括函数的形参这些空间也是包含在其中。函数调用本质是指令跳转,会调用栈区空间,如果栈区空间沾满导致程序崩溃
不仅栈区,一个应用程序在应用过程中,还存在另外四个区,如下

功能:
堆区:必须向操作系统申请,用完就还
字符串常量区:存放字符串常量的,即双引号内“”
代码区:存放代码。字符型常量也在其中
静态区:函数内的静态局部变量及函数外的全局变量
例:char s[10] = "Hello" 其中s在栈区,“Hello”在字符串常量区
函数的传参
传递方式——值传递
在c语言中,函数传参都是以值传递的方式,只是将实参的值传递给形参,而并没有把实参本身传递给形参,以以下代码为例。

输出i的值为20而并非30。因为在对形参n开辟空间时,用实参i来对n进行初始化,然后对n进行操作,根本不改变i的值,即无法在被调函数里修改主调,而能改变的是指针传参
传参方向——自右向左
当函数有两个及以上参数时,传参时先传右侧,再传左侧,以以下代码为例。

先输出10,再输出20,最后输出30。
在此期间,禁止使用同一变量的自增自减(如下),否则结果不确定
![]()
数组作为函数参数
数组作为函数参数时,需要传两个参数,一个是数组名,一个是数组元素的个数,以计算数组内数总和为例。

形参数组a[]可以不指定大小,因为c语言编译只将实参首元素地址传递给形参。
应该强调的是,用数组名作为函数实参时,并不是把数组元素的值传递给形参,而是把实参数组的首元素地址传递给形参数组,这样两个数组就攻占同一段内存单元,所以当改变其中一个的值时,另一个也会随之改变,也就是说,形参数组中各元素的值如果发生变化,会使得实参数组的值同时发生变化。
例:求数列中最大值函数
#include <stdio.h>
int max(int a[], int len)
{
int max = a[0];
for(int i = 1; i < len; ++i)
{
if(max < a[i])
{
max = a[i];
}
}
return max;
}
int main()
{
int a[] = {13,5,152,853,12,56,123};
printf("%d\n", max(a, 7));
}
各种string类型函数的拆分
strcpy
strlen

strcmp
strcat
二维数组
我们已经知道,二维数组可以看作多个一维数组组成,所以可以试着采用一维数组的方式。
二维数组作为形参时,第二维也就是列数是固定的,也就是说,在二维数组函数中,需要给出二维数组的行数,但是由于列数是固定的,所以在函数中包括循环终止等操作可以以固定的数位基准,虽然可以通过sizeof得出列数,但是完全没有必要。
例:求出二维数组边界总和
#include <stdio.h>
int sums(int a[][4], int rows)
{
int sums = 0;
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < 4; ++j)
{
if(i == 0 || i == rows - 1 || j == 0 || j == 3)
{
sums += a[i][j];
}
}
}
return sums;
}
int main()
{
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
int rows = sizeof(a) / sizeof(a[0]);
printf("%d\n", sums(a, rows));
}
更多推荐






所有评论(0)