目录
1.函数的概念
函数(function)的概念,有些翻译为:⼦程序,⼦程序这种翻译更加准确⼀些。 C语⾔中的函数就是⼀个完成某项特定的任务的⼀⼩段代码。
在C语⾔中我们⼀般会⻅到两类函数:
• 库函数
• ⾃定义函数
2.库函数
C语⾔标准中规定了C语⾔的各种语法规则,C语⾔并不提供库函数;C语⾔的国际标准ANSI C规定了⼀ 些常⽤的函数的标准,被称为标准库,那不同的编译器⼚商根据ANSI提供的C语⾔标准就给出了⼀系列 函数的实现。这些函数就被称为库函数。
3.函数的语法形式
ret_type fun_name(形式参数)
{
}
ret_type 是函数返回类型
• fun_name 是函数名
• 括号中放的是形式参数
• {}括起来的是函数体
这个图非常直观的可以看出 函数的类型,结构
4 函数的举例函数的举例
写⼀个加法函数,完成2个整型变量的加法操作。
#include <stdio.h>
int Add(int x, int y)//函数实现 用两个整形接收
{
return x + y;//返回X+Y
}
int main()
{
int a = 10;//把10赋值给a
int b = 20;//把20赋值给b
int r= Add(a, b);//创建函数Add
printf("%d ", r);
return 0;
}
5. 形参和实参
实参
调⽤Add函数时,传递给函数的参数a和b,称为实际参数,简称实参。 实际参数就是真实传递给函数的参数。
形参
在函数名 Add 后的括号中写的 x 和 y ,称为形式参数,简 称形参。
6 实参和形参的关系
我们在调试的时候可以观察到,x和y确实得到了a和b的值,但是x和y的地址和a和b的地址是不⼀样 的,所以我们可以理解为形参是实参的⼀份临时拷⻉
7 return语句
• return后边可以是⼀个数值,也可以是⼀个表达式,如果是表达式则先执⾏表达式,再返回表达式 的结果。
#include <stdio.h>
int test( int i)
{
if (i >= 0)
return 1;
else
return -1;//return 返回的是数值
}
int main()
{
int a = 0;
scanf("%d", &a);
int r= test(a);
printf("%d ", r);
return 0;
}
• return后边也可以什么都没有,直接写 return; 这种写法适合函数返回类型是void的情况。
void test()
{
printf("haha\n");//return语句后也可以什么都不加,表示无返回类型,与void连用
if ( 1)
return;
printf("nihao \n");
}
int main()
{
test();
return 0;
}
• return返回的值和函数返回类型不⼀致,系统会⾃动将返回的值隐式转换为函数的返回类型。
• return语句执⾏后,函数就彻底返回,后边的代码不再执⾏。
• 如果函数中存在if等分⽀的语句,则要保证每种情况下都有return返回,否则会出现编译错误。
8 数组做函数参数
写⼀个函数将⼀个整型数组的内容,全部置为-1,再写⼀个函数打印数组的内容。
#include <stdio.h>
void set_arr(int arr[10], int sz, int set)//接收 数组,个数,初始化的内容
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
arr[i] = set;//改成set会灵活些
}
printf("\n");
}
void print_arr(int arr[10], int sz)//打印接收 数组,个数
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof arr[0];
set_arr( arr ,sz,-1 );//传参内容是数组,个数,初始化的内容
print_arr(arr, sz);//打印的内容
return 0;
}v
1实参是数组 ,形参也得是数组
2形参的变量名和实参的变量名可以是相同的。
3函数在设计的时候可以单一些
4数组在传参的时候,实参的数组和形参的数组是同一个。
打二维数组内容
#include <stdio.h>
void print(int arr[3][5], int c, int l)//这里的行数可以省略,和之前的二位数组一样
{
int i = 0;
for (i = 0; i < c; i++)//打印行
{
int j = 0;
for (j = 0; j < l; j++)//打印列
{
printf("%d ", arr[i][j]);//打印的下标为3行5列的元素
}
}
}
int main()
{
int arr[3][5] = { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7 };
print(arr, 3, 5);//3和5 是行和列
return 0;
}
9 嵌套调⽤和链式访问
9.1嵌套调⽤
假设我们计算某年某⽉有多少天?如果要函数实现,可以设计2个函数:
• is_leap_year():根据年份确定是否是闰年
• get_days_of_month():调⽤is_leap_year确定是否是闰年后,再根据⽉计算这个⽉的天数
#include <stdio.h>
int is_lelp_year(int y)//是否为闰年
{
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
return 1;
else
return 0;
}
int get_days_of_month(int y, int m)
{
int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//前面加一个0是为了方便下标和元素月份对应
int day = days[m];//月份对应的元素赋值给day
if (is_lelp_year(y) == 1 && m == 2)//如果年份是闰年并且m是2月 那么2月对应的天数加1
{
day++;
}
return day;
}
int main()
{
int year = 0;
int month = 0;
scanf("%d %d", &year, &month);
int r = get_days_of_month(year, month);
printf("%d ", r);
return 0;
}
10 链式访问
所谓链式访问就是将⼀个函数的返回值作为另外⼀个函数的参数,像链条⼀样将函数串起来就是函数 的链式访问。
#include<stdio.h>
int main()
{
int len = strlen("abcdef");//1.strlen求⼀个字符串的⻓度
printf("%d\n", len);//2.打印⻓度
return 0;
}
前⾯的代码完成动作写了2条语句,把如果把strlen的返回值直接作为printf函数的参数呢?这样就是⼀ 个链式访问的例⼦了。
#include <string.h>
int main()
{
printf("%d ",strlen("abcdef"));//这个就叫链式访问
return 0;
}
#include <stdio.h>
int main()
{
printf("%d", printf("%d ", printf("%d ", 43)));//空格也算字符 加了空格就是4332 不+就是4321
return 0;
}
11. 函数的声明和定义
函数要满足先声明后定义
#include <stdio.h>
int is_lelp_year(int y);//函数声明
int main()
{
int year = 0;
scanf("%d", &year );
int r = is_lelp_year(year);//函数调用
}
int is_lelp_year(int y)// 在函数声明中 形参变量名可以省略
{
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
{
printf("是闰年\n");
}
else
{
printf("不是闰年\n");
}
return 0;
}
函数的定义也是⼀种特殊的声明,所以如果函数定义放在调⽤之前也是可以的。
12.多个⽂件
⼀般在企业中我们写代码时候,代码可能⽐较多,不会将所有的代码都放在⼀个⽂件中;我们往往会 根据程序的功能,将代码拆分放在多个⽂件中。 ⼀般情况下,函数的声明、类型的声明放在头⽂件(.h)中,函数的实现是放在源⽂件(.c)⽂件中。
包含自己的头文件是 #include“ 文件名”
代码的隐藏:如果不想让别人看见代码
首先找到自己的文件 在上面右击它 直到最下边有个属性,点击
在 常规 里面找到 配置类型 默认是应用程序exe 点击把它改成 动态库 。lib 最后点击应用
运行一下代码生成静态库lib文件
按照这个路径找静态库所在的位置
找到这个文件,发现用记事本打开会出现下面情况
当你用编译器打开这个文件的时候,文件报错了
这时候代码就隐藏了 ,保留了源文件
买来的文件怎么用呢,这时候你要在使用的工程里导入静态库 #pragma comment (lib," 文件名.后缀" );即可
13.static 和 extern
static 和 extern 都是C语⾔中的关键字。
static 是 静态的 的意思,可以⽤来:
• 修饰局部变量
• 修饰全局变量
• 修饰函数
extern 是⽤来声明外部符号的。
作⽤域(scope)是程序设计概念
1. 局部变量的作⽤域是变量所在的局部范围。
2. 全局变量的作⽤域是整个⼯程(项⽬)。
⽣命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的⼀个时间段。
1. 局部变量的⽣命周期是:进⼊作⽤域变量创建,⽣命周期开始,出作⽤域⽣命周期结束。
2. 全局变量的⽣命周期是:整个程序的⽣命周期。