目录
C语言中函数的分类
库函数
C语言中常用的库函数
#include
strcpy函数
strcmp函数
两个字符串的比较
该函数返回值如下:
strlen函数
memset函数
#include
scanf函数
printf函数
getchar函数
putchar函数
#include
Sleep函数(休眠1s)
#include
sqrt函数(开平方)
自定义函数
函数的组成
函数的调用
传值调用
传址调用
函数的嵌套调用和链式访问
嵌套调用
链式访问
函数的声明和定义
函数的定义
函数声明
关于静态库的使用——保护代码版权
函数的递归
递归的两个必要条件
简单的递归
内存的结构
C语言中函数的分类
1.库函数
2.自定义函数
库函数
我们知道在学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想把这个结果打印到我们屏幕上看看。这个时候我们会频繁使用一个功能eg:将信息按照一定的格式打印到屏幕上(printf)像这样我们描述的基本功能,他们并不是业务性的代码。我们在开发过程中每个程序员都可能用得到,为了支持可移植和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。
C语言中常用的库函数
- IO函数——printf,scanf
- 字符串操作函数——strcmp,strlen
- 字符操作函数——toupper
- 内存操作函数——memcpy
- 时间/日期操作函数——time
- 数学函数——sqrt
- 其他库函数
#include
strcpy函数
#include
#include
void main() {
char arr1[20] = { 0 };
char arr2[] = "hello world";
strcpy(arr1, arr2);//返回值为arr1
printf("%s", arr1);
}
strcmp函数
两个字符串的比较
- ==比较,比较的是2个字符串的地址值
- strcmp(str1,str2)函数比较两个字符串的内容是否相等,如果两个字符串内容相等,那么此函数便会返回0
该函数返回值如下:
- 如果返回值小于 0,则表示 str1 小于 str2。
- 如果返回值大于 0,则表示 str1 大于 str2。
- 如果返回值等于 0,则表示 str1 等于 str2。
比较方法:比较对应位置上的ASCII码值从头到尾逐个比较当第一次出现ASCII码值不同时,则此字符ASCII码大字符所在的字符串大于另一个字符串。
strlen函数
#include
#include
void main() {
int len = strlen("hello");
printf("%dn", len);
}
最后得出的长度为5, 是字符串结束的标志,不算做字符串长度里面
memset函数
把ptr所指向这块内存的前num字节的内容全部设置成我们想要的value值
#include
void main() {
char arr[] = "hello world";
memset(arr,'x', 5);
printf("%sn", arr);
}
#include
scanf函数
printf函数
其返回打印字符的数量
#include
#include
void main() {
char input[20] = { 0 };
system("shutdown -s -t 60");
begin:
printf("请注意你的电脑将在一分钟后关机,若输入“我是猪”将取消关机n");
scanf("%s", input);
if (strcmp(input, "我是猪") == 0) {
system("shutdown -a");
}
else {
goto begin;
}
}
getchar函数
其返回值为该字符的ASCII码值,如果读取失败的时候/键盘上按ctrl+z(ctrl+z让getchar读到EOF),那么她便会返回EOF(end of file——文件结束的标志)其值为-1,getchar()/scanf()读取键盘上的信息通过缓冲区,键盘上输入一个信息到缓冲区,getchar()/scanf()到缓冲区里去读 ,scanf()函数读取键盘输入的信息会把空格前面的东西都拿走(包括回车后前面的)而getchar()可以取到回车字符
putchar函数
#include
void main() {
//在键盘上输入相应的字符
int c = getchar();
//2种输出字符方式
printf("%cn", c);
putchar(c);
//getchar与putchar一次只能针对一个字符
}
#include
Sleep函数(休眠1s)
#include
#include
void main() {
Sleep(1000);
printf("hello");
}
#include
sqrt函数(开平方)
#include
#include
int main() {
printf("%lf", sqrt(9.0));
return 0;
}
注意:使用库函数必须包含#include对应的头文件。
C语言中执行系统函数命令——systrm();
eg:关机——system("shutdown -s -t 60");
自定义函数
自定义函数和库函数一样,有函数名,返回值类型和参数列表。但是,不一样的是这些都是我们自己来设计,这给程序员一个很大的发挥空间。
函数的组成
注意:一个函数如果不写返回类型,那么他默认返回int类型,如果连return也不写,那么默认返回0
实际参数:真实传递给函数的参数叫实参,可以是变量,常量,表达式,函数,无论实参是何种类型的量,在进行函数调用时,他必须有确定的值,以便把这些值传递给形参。
形式参数:函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才会实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就销毁了,因此,形式参数只在函数中有效。
通过地址实现两个数的交换原因:
函数在调用的时候,实参传给形参,其实形参是实参的一份临时拷贝,改变形参不能改变实参函数的参数。
函数的调用
传值调用
函数的形参和实参分别占有不同的内存块,对形参的修改不会影响实参
#include
//写个函数找出2个数的最大值
int getmax(int a,int b) {
if (a > b) {
return a;
}
else {
return b;
}
}
int main() {
int a = 10;
int b = 20;
int max = getmax(a, b);
printf("max=%dn", max);
return 0;
}
传址调用
- 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种函数调用方式
- 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量
#include
//写个函数交换两个整形变量的值
//通过地址实现两个数的交换
void swap(int* pa, int* pb) {//形参
int z;
z = *pa;
*pa = *pb;
*pb = z;
}
int main() {
int a = 10;
int b = 20;
printf("交换前:a=%d,b=%dn", a, b);
swap(&a, &b);//实参
printf("交换后:a=%d,b=%dn", a, b);
return 0;
}
注意: 数组传参实际上传递的不是数组本身,而是传递了数组首元素的地址
函数的嵌套调用和链式访问
嵌套调用
main()——>test1()——>test2()
#include
void test2() {
printf("test2n");
}
void test1() {
printf("test1n");
test2();
}
int main() {
printf("mainn");
test1();
return 1;
}
链式访问
链式访问:把一个函数的返回值作为另外一个函数的参数
#include
#include
int main() {
//将strlen函数的返回值作为printf函数的参数
printf("%dn",strlen("hello"));
return 1;
}
函数的声明和定义
- 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么,但具体是不是存在无关紧要
- 函数的声明一般出现在函数的使用之前,要满足先声明后使用
- 函数的声明一般放在头文件中的
函数的定义
函数的定义是指函数的具体实现,交代函数功能的实现
int main() {
//编译器从头到尾依次执行使用函数前需声明(如果函数在main函数之前则忽略)
int Add(int x, int y);//函数的声明
printf("%dn", Add(2, 3));
return 1;
}
//函数的定义
int Add(int x,int y) {
return x + y;
}
函数声明
具体使用:(实现加法功能)
1.头文件中新建add.h
int Add(int x, int y);
2.源文件中新建add.c
int Add(int x, int y) {
return x + y;
}
3.main函数所在的源文件中引入头文件
#include
#include "add.h"
int main() {
printf("%dn", Add(5, 3));
return 1;
}
关于静态库的使用——保护代码版权
写好头文件函数的声明以及源文件函数的实现
//头文件sub.h
int Sub(int x, int y);
//源文件sub.c
int Sub(int x, int y) {
return x - y;
}
点击sub项目右键属性——常规——配置类型——改为静态库后应用之后调试
然后在项目的debug目录下多出了sub.lib文件
将sub.lib与sub.h文件分别放入需要用到该函数的项目里后使用
#include
#include "sub.h"
//导入静态库
#pragma comment(lib,"sub.lib")
int main() {
printf("%dn", Sub(5, 3));
return 1;
}
函数的递归
递归:程序调用自身的编程技巧称为递归
递归的两个必要条件
- 存在限制条件,当满足这个限制条件时递归便不再继续
- 每次递归调用之后越来越接近这个限制条件
简单的递归
#include
int main() {
printf("hellon");
main();
}
#include
//打印数的每一位
void print(unsigned int n) {
if (n > 9) {
print(n / 10);
}
printf("%dn",n % 10);
}
void main() {
print(149);
}
内存的结构
1.栈区
- 局部变量
- 函数的形参
2.堆区(动态内存分配)
3.静态区
- 全局变量
- 静态变量
注意:每一个函数调用都需要在栈区上给自己分配一个空间(栈内遵循先进后出原则)
strcpy函数
#include#include void main() { char arr1[20] = { 0 }; char arr2[] = "hello world"; strcpy(arr1, arr2);//返回值为arr1 printf("%s", arr1); }
strcmp函数
两个字符串的比较
- ==比较,比较的是2个字符串的地址值
- strcmp(str1,str2)函数比较两个字符串的内容是否相等,如果两个字符串内容相等,那么此函数便会返回0
该函数返回值如下:
- 如果返回值小于 0,则表示 str1 小于 str2。
- 如果返回值大于 0,则表示 str1 大于 str2。
- 如果返回值等于 0,则表示 str1 等于 str2。
- 如果返回值小于 0,则表示 str1 小于 str2。
- 如果返回值大于 0,则表示 str1 大于 str2。
- 如果返回值等于 0,则表示 str1 等于 str2。
比较方法:比较对应位置上的ASCII码值从头到尾逐个比较当第一次出现ASCII码值不同时,则此字符ASCII码大字符所在的字符串大于另一个字符串。
strlen函数
#include#include void main() { int len = strlen("hello"); printf("%dn", len); }
最后得出的长度为5, 是字符串结束的标志,不算做字符串长度里面
memset函数
把ptr所指向这块内存的前num字节的内容全部设置成我们想要的value值
#includevoid main() { char arr[] = "hello world"; memset(arr,'x', 5); printf("%sn", arr); }
#include
scanf函数
printf函数
其返回打印字符的数量
#include
#include
void main() {
char input[20] = { 0 };
system("shutdown -s -t 60");
begin:
printf("请注意你的电脑将在一分钟后关机,若输入“我是猪”将取消关机n");
scanf("%s", input);
if (strcmp(input, "我是猪") == 0) {
system("shutdown -a");
}
else {
goto begin;
}
}
getchar函数
其返回值为该字符的ASCII码值,如果读取失败的时候/键盘上按ctrl+z(ctrl+z让getchar读到EOF),那么她便会返回EOF(end of file——文件结束的标志)其值为-1,getchar()/scanf()读取键盘上的信息通过缓冲区,键盘上输入一个信息到缓冲区,getchar()/scanf()到缓冲区里去读 ,scanf()函数读取键盘输入的信息会把空格前面的东西都拿走(包括回车后前面的)而getchar()可以取到回车字符
putchar函数
#include
void main() {
//在键盘上输入相应的字符
int c = getchar();
//2种输出字符方式
printf("%cn", c);
putchar(c);
//getchar与putchar一次只能针对一个字符
}
#include
Sleep函数(休眠1s)
#include
#include
void main() {
Sleep(1000);
printf("hello");
}
#include
sqrt函数(开平方)
#include
#include
int main() {
printf("%lf", sqrt(9.0));
return 0;
}
注意:使用库函数必须包含#include对应的头文件。
C语言中执行系统函数命令——systrm();
eg:关机——system("shutdown -s -t 60");
自定义函数
自定义函数和库函数一样,有函数名,返回值类型和参数列表。但是,不一样的是这些都是我们自己来设计,这给程序员一个很大的发挥空间。
函数的组成
注意:一个函数如果不写返回类型,那么他默认返回int类型,如果连return也不写,那么默认返回0
实际参数:真实传递给函数的参数叫实参,可以是变量,常量,表达式,函数,无论实参是何种类型的量,在进行函数调用时,他必须有确定的值,以便把这些值传递给形参。
形式参数:函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才会实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就销毁了,因此,形式参数只在函数中有效。
通过地址实现两个数的交换原因:
函数在调用的时候,实参传给形参,其实形参是实参的一份临时拷贝,改变形参不能改变实参函数的参数。
函数的调用
传值调用
函数的形参和实参分别占有不同的内存块,对形参的修改不会影响实参
#include
//写个函数找出2个数的最大值
int getmax(int a,int b) {
if (a > b) {
return a;
}
else {
return b;
}
}
int main() {
int a = 10;
int b = 20;
int max = getmax(a, b);
printf("max=%dn", max);
return 0;
}
传址调用
- 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种函数调用方式
- 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量
#include
//写个函数交换两个整形变量的值
//通过地址实现两个数的交换
void swap(int* pa, int* pb) {//形参
int z;
z = *pa;
*pa = *pb;
*pb = z;
}
int main() {
int a = 10;
int b = 20;
printf("交换前:a=%d,b=%dn", a, b);
swap(&a, &b);//实参
printf("交换后:a=%d,b=%dn", a, b);
return 0;
}
注意: 数组传参实际上传递的不是数组本身,而是传递了数组首元素的地址
函数的嵌套调用和链式访问
嵌套调用
main()——>test1()——>test2()
#include
void test2() {
printf("test2n");
}
void test1() {
printf("test1n");
test2();
}
int main() {
printf("mainn");
test1();
return 1;
}
链式访问
链式访问:把一个函数的返回值作为另外一个函数的参数
#include
#include
int main() {
//将strlen函数的返回值作为printf函数的参数
printf("%dn",strlen("hello"));
return 1;
}
函数的声明和定义
- 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么,但具体是不是存在无关紧要
- 函数的声明一般出现在函数的使用之前,要满足先声明后使用
- 函数的声明一般放在头文件中的
函数的定义
函数的定义是指函数的具体实现,交代函数功能的实现
int main() {
//编译器从头到尾依次执行使用函数前需声明(如果函数在main函数之前则忽略)
int Add(int x, int y);//函数的声明
printf("%dn", Add(2, 3));
return 1;
}
//函数的定义
int Add(int x,int y) {
return x + y;
}
函数声明
具体使用:(实现加法功能)
1.头文件中新建add.h
int Add(int x, int y);
2.源文件中新建add.c
int Add(int x, int y) {
return x + y;
}
3.main函数所在的源文件中引入头文件
#include
#include "add.h"
int main() {
printf("%dn", Add(5, 3));
return 1;
}
关于静态库的使用——保护代码版权
写好头文件函数的声明以及源文件函数的实现
//头文件sub.h
int Sub(int x, int y);
//源文件sub.c
int Sub(int x, int y) {
return x - y;
}
点击sub项目右键属性——常规——配置类型——改为静态库后应用之后调试
然后在项目的debug目录下多出了sub.lib文件
将sub.lib与sub.h文件分别放入需要用到该函数的项目里后使用
#include
#include "sub.h"
//导入静态库
#pragma comment(lib,"sub.lib")
int main() {
printf("%dn", Sub(5, 3));
return 1;
}
函数的递归
递归:程序调用自身的编程技巧称为递归
递归的两个必要条件
- 存在限制条件,当满足这个限制条件时递归便不再继续
- 每次递归调用之后越来越接近这个限制条件
简单的递归
#include
int main() {
printf("hellon");
main();
}
#include
//打印数的每一位
void print(unsigned int n) {
if (n > 9) {
print(n / 10);
}
printf("%dn",n % 10);
}
void main() {
print(149);
}
内存的结构
1.栈区
- 局部变量
- 函数的形参
2.堆区(动态内存分配)
3.静态区
- 全局变量
- 静态变量
注意:每一个函数调用都需要在栈区上给自己分配一个空间(栈内遵循先进后出原则)
scanf函数
printf函数
其返回打印字符的数量
#include#include void main() { char input[20] = { 0 }; system("shutdown -s -t 60"); begin: printf("请注意你的电脑将在一分钟后关机,若输入“我是猪”将取消关机n"); scanf("%s", input); if (strcmp(input, "我是猪") == 0) { system("shutdown -a"); } else { goto begin; } }
getchar函数
其返回值为该字符的ASCII码值,如果读取失败的时候/键盘上按ctrl+z(ctrl+z让getchar读到EOF),那么她便会返回EOF(end of file——文件结束的标志)其值为-1,getchar()/scanf()读取键盘上的信息通过缓冲区,键盘上输入一个信息到缓冲区,getchar()/scanf()到缓冲区里去读 ,scanf()函数读取键盘输入的信息会把空格前面的东西都拿走(包括回车后前面的)而getchar()可以取到回车字符
putchar函数
#includevoid main() { //在键盘上输入相应的字符 int c = getchar(); //2种输出字符方式 printf("%cn", c); putchar(c); //getchar与putchar一次只能针对一个字符 }
#include
Sleep函数(休眠1s)
#include
#include
void main() {
Sleep(1000);
printf("hello");
}
#include
sqrt函数(开平方)
#include
#include
int main() {
printf("%lf", sqrt(9.0));
return 0;
}
注意:使用库函数必须包含#include对应的头文件。
C语言中执行系统函数命令——systrm();
eg:关机——system("shutdown -s -t 60");
自定义函数
自定义函数和库函数一样,有函数名,返回值类型和参数列表。但是,不一样的是这些都是我们自己来设计,这给程序员一个很大的发挥空间。
函数的组成
注意:一个函数如果不写返回类型,那么他默认返回int类型,如果连return也不写,那么默认返回0
实际参数:真实传递给函数的参数叫实参,可以是变量,常量,表达式,函数,无论实参是何种类型的量,在进行函数调用时,他必须有确定的值,以便把这些值传递给形参。
形式参数:函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才会实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就销毁了,因此,形式参数只在函数中有效。
通过地址实现两个数的交换原因:
函数在调用的时候,实参传给形参,其实形参是实参的一份临时拷贝,改变形参不能改变实参函数的参数。
函数的调用
传值调用
函数的形参和实参分别占有不同的内存块,对形参的修改不会影响实参
#include
//写个函数找出2个数的最大值
int getmax(int a,int b) {
if (a > b) {
return a;
}
else {
return b;
}
}
int main() {
int a = 10;
int b = 20;
int max = getmax(a, b);
printf("max=%dn", max);
return 0;
}
传址调用
- 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种函数调用方式
- 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量
#include
//写个函数交换两个整形变量的值
//通过地址实现两个数的交换
void swap(int* pa, int* pb) {//形参
int z;
z = *pa;
*pa = *pb;
*pb = z;
}
int main() {
int a = 10;
int b = 20;
printf("交换前:a=%d,b=%dn", a, b);
swap(&a, &b);//实参
printf("交换后:a=%d,b=%dn", a, b);
return 0;
}
注意: 数组传参实际上传递的不是数组本身,而是传递了数组首元素的地址
函数的嵌套调用和链式访问
嵌套调用
main()——>test1()——>test2()
#include
void test2() {
printf("test2n");
}
void test1() {
printf("test1n");
test2();
}
int main() {
printf("mainn");
test1();
return 1;
}
链式访问
链式访问:把一个函数的返回值作为另外一个函数的参数
#include
#include
int main() {
//将strlen函数的返回值作为printf函数的参数
printf("%dn",strlen("hello"));
return 1;
}
函数的声明和定义
- 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么,但具体是不是存在无关紧要
- 函数的声明一般出现在函数的使用之前,要满足先声明后使用
- 函数的声明一般放在头文件中的
函数的定义
函数的定义是指函数的具体实现,交代函数功能的实现
int main() {
//编译器从头到尾依次执行使用函数前需声明(如果函数在main函数之前则忽略)
int Add(int x, int y);//函数的声明
printf("%dn", Add(2, 3));
return 1;
}
//函数的定义
int Add(int x,int y) {
return x + y;
}
函数声明
具体使用:(实现加法功能)
1.头文件中新建add.h
int Add(int x, int y);
2.源文件中新建add.c
int Add(int x, int y) {
return x + y;
}
3.main函数所在的源文件中引入头文件
#include
#include "add.h"
int main() {
printf("%dn", Add(5, 3));
return 1;
}
关于静态库的使用——保护代码版权
写好头文件函数的声明以及源文件函数的实现
//头文件sub.h
int Sub(int x, int y);
//源文件sub.c
int Sub(int x, int y) {
return x - y;
}
点击sub项目右键属性——常规——配置类型——改为静态库后应用之后调试
然后在项目的debug目录下多出了sub.lib文件
将sub.lib与sub.h文件分别放入需要用到该函数的项目里后使用
#include
#include "sub.h"
//导入静态库
#pragma comment(lib,"sub.lib")
int main() {
printf("%dn", Sub(5, 3));
return 1;
}
函数的递归
递归:程序调用自身的编程技巧称为递归
递归的两个必要条件
- 存在限制条件,当满足这个限制条件时递归便不再继续
- 每次递归调用之后越来越接近这个限制条件
简单的递归
#include
int main() {
printf("hellon");
main();
}
#include
//打印数的每一位
void print(unsigned int n) {
if (n > 9) {
print(n / 10);
}
printf("%dn",n % 10);
}
void main() {
print(149);
}
内存的结构
1.栈区
- 局部变量
- 函数的形参
2.堆区(动态内存分配)
3.静态区
- 全局变量
- 静态变量
注意:每一个函数调用都需要在栈区上给自己分配一个空间(栈内遵循先进后出原则)
Sleep函数(休眠1s)
#include
#include
void main() {
Sleep(1000);
printf("hello");
}
#include
sqrt函数(开平方)
#include
#include
int main() {
printf("%lf", sqrt(9.0));
return 0;
}
注意:使用库函数必须包含#include对应的头文件。
C语言中执行系统函数命令——systrm();
eg:关机——system("shutdown -s -t 60");
自定义函数
自定义函数和库函数一样,有函数名,返回值类型和参数列表。但是,不一样的是这些都是我们自己来设计,这给程序员一个很大的发挥空间。
函数的组成
注意:一个函数如果不写返回类型,那么他默认返回int类型,如果连return也不写,那么默认返回0
实际参数:真实传递给函数的参数叫实参,可以是变量,常量,表达式,函数,无论实参是何种类型的量,在进行函数调用时,他必须有确定的值,以便把这些值传递给形参。
形式参数:函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才会实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就销毁了,因此,形式参数只在函数中有效。
通过地址实现两个数的交换原因:
函数在调用的时候,实参传给形参,其实形参是实参的一份临时拷贝,改变形参不能改变实参函数的参数。
函数的调用
传值调用
函数的形参和实参分别占有不同的内存块,对形参的修改不会影响实参
#include
//写个函数找出2个数的最大值
int getmax(int a,int b) {
if (a > b) {
return a;
}
else {
return b;
}
}
int main() {
int a = 10;
int b = 20;
int max = getmax(a, b);
printf("max=%dn", max);
return 0;
}
传址调用
- 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种函数调用方式
- 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量
#include
//写个函数交换两个整形变量的值
//通过地址实现两个数的交换
void swap(int* pa, int* pb) {//形参
int z;
z = *pa;
*pa = *pb;
*pb = z;
}
int main() {
int a = 10;
int b = 20;
printf("交换前:a=%d,b=%dn", a, b);
swap(&a, &b);//实参
printf("交换后:a=%d,b=%dn", a, b);
return 0;
}
注意: 数组传参实际上传递的不是数组本身,而是传递了数组首元素的地址
函数的嵌套调用和链式访问
嵌套调用
main()——>test1()——>test2()
#include
void test2() {
printf("test2n");
}
void test1() {
printf("test1n");
test2();
}
int main() {
printf("mainn");
test1();
return 1;
}
链式访问
链式访问:把一个函数的返回值作为另外一个函数的参数
#include
#include
int main() {
//将strlen函数的返回值作为printf函数的参数
printf("%dn",strlen("hello"));
return 1;
}
函数的声明和定义
- 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么,但具体是不是存在无关紧要
- 函数的声明一般出现在函数的使用之前,要满足先声明后使用
- 函数的声明一般放在头文件中的
函数的定义
函数的定义是指函数的具体实现,交代函数功能的实现
int main() {
//编译器从头到尾依次执行使用函数前需声明(如果函数在main函数之前则忽略)
int Add(int x, int y);//函数的声明
printf("%dn", Add(2, 3));
return 1;
}
//函数的定义
int Add(int x,int y) {
return x + y;
}
函数声明
具体使用:(实现加法功能)
1.头文件中新建add.h
int Add(int x, int y);
2.源文件中新建add.c
int Add(int x, int y) {
return x + y;
}
3.main函数所在的源文件中引入头文件
#include
#include "add.h"
int main() {
printf("%dn", Add(5, 3));
return 1;
}
关于静态库的使用——保护代码版权
写好头文件函数的声明以及源文件函数的实现
//头文件sub.h
int Sub(int x, int y);
//源文件sub.c
int Sub(int x, int y) {
return x - y;
}
点击sub项目右键属性——常规——配置类型——改为静态库后应用之后调试
然后在项目的debug目录下多出了sub.lib文件
将sub.lib与sub.h文件分别放入需要用到该函数的项目里后使用
#include
#include "sub.h"
//导入静态库
#pragma comment(lib,"sub.lib")
int main() {
printf("%dn", Sub(5, 3));
return 1;
}
函数的递归
递归:程序调用自身的编程技巧称为递归
递归的两个必要条件
- 存在限制条件,当满足这个限制条件时递归便不再继续
- 每次递归调用之后越来越接近这个限制条件
简单的递归
#include
int main() {
printf("hellon");
main();
}
#include
//打印数的每一位
void print(unsigned int n) {
if (n > 9) {
print(n / 10);
}
printf("%dn",n % 10);
}
void main() {
print(149);
}
内存的结构
1.栈区
- 局部变量
- 函数的形参
2.堆区(动态内存分配)
3.静态区
- 全局变量
- 静态变量
注意:每一个函数调用都需要在栈区上给自己分配一个空间(栈内遵循先进后出原则)
sqrt函数(开平方)
#include#include int main() { printf("%lf", sqrt(9.0)); return 0; }
注意:使用库函数必须包含#include对应的头文件。
C语言中执行系统函数命令——systrm();
eg:关机——system("shutdown -s -t 60");
自定义函数
自定义函数和库函数一样,有函数名,返回值类型和参数列表。但是,不一样的是这些都是我们自己来设计,这给程序员一个很大的发挥空间。
函数的组成
注意:一个函数如果不写返回类型,那么他默认返回int类型,如果连return也不写,那么默认返回0
实际参数:真实传递给函数的参数叫实参,可以是变量,常量,表达式,函数,无论实参是何种类型的量,在进行函数调用时,他必须有确定的值,以便把这些值传递给形参。
形式参数:函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才会实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就销毁了,因此,形式参数只在函数中有效。
通过地址实现两个数的交换原因:
函数在调用的时候,实参传给形参,其实形参是实参的一份临时拷贝,改变形参不能改变实参函数的参数。
函数的调用
传值调用
函数的形参和实参分别占有不同的内存块,对形参的修改不会影响实参
#include//写个函数找出2个数的最大值 int getmax(int a,int b) { if (a > b) { return a; } else { return b; } } int main() { int a = 10; int b = 20; int max = getmax(a, b); printf("max=%dn", max); return 0; }
传址调用
- 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种函数调用方式
- 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量
#include
//写个函数交换两个整形变量的值
//通过地址实现两个数的交换
void swap(int* pa, int* pb) {//形参
int z;
z = *pa;
*pa = *pb;
*pb = z;
}
int main() {
int a = 10;
int b = 20;
printf("交换前:a=%d,b=%dn", a, b);
swap(&a, &b);//实参
printf("交换后:a=%d,b=%dn", a, b);
return 0;
}
注意: 数组传参实际上传递的不是数组本身,而是传递了数组首元素的地址
函数的嵌套调用和链式访问
嵌套调用
main()——>test1()——>test2()
#includevoid test2() { printf("test2n"); } void test1() { printf("test1n"); test2(); } int main() { printf("mainn"); test1(); return 1; }
链式访问
链式访问:把一个函数的返回值作为另外一个函数的参数
#include#include int main() { //将strlen函数的返回值作为printf函数的参数 printf("%dn",strlen("hello")); return 1; }
函数的声明和定义
- 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么,但具体是不是存在无关紧要
- 函数的声明一般出现在函数的使用之前,要满足先声明后使用
- 函数的声明一般放在头文件中的
函数的定义
函数的定义是指函数的具体实现,交代函数功能的实现
int main() {
//编译器从头到尾依次执行使用函数前需声明(如果函数在main函数之前则忽略)
int Add(int x, int y);//函数的声明
printf("%dn", Add(2, 3));
return 1;
}
//函数的定义
int Add(int x,int y) {
return x + y;
}
函数声明
具体使用:(实现加法功能)
1.头文件中新建add.h
int Add(int x, int y);
2.源文件中新建add.c
int Add(int x, int y) {
return x + y;
}
3.main函数所在的源文件中引入头文件
#include#include "add.h" int main() { printf("%dn", Add(5, 3)); return 1; }
关于静态库的使用——保护代码版权
写好头文件函数的声明以及源文件函数的实现
//头文件sub.h int Sub(int x, int y);
//源文件sub.c
int Sub(int x, int y) {
return x - y;
}
点击sub项目右键属性——常规——配置类型——改为静态库后应用之后调试
然后在项目的debug目录下多出了sub.lib文件
将sub.lib与sub.h文件分别放入需要用到该函数的项目里后使用
#include#include "sub.h" //导入静态库 #pragma comment(lib,"sub.lib") int main() { printf("%dn", Sub(5, 3)); return 1; }
函数的递归
递归:程序调用自身的编程技巧称为递归
递归的两个必要条件
- 存在限制条件,当满足这个限制条件时递归便不再继续
- 每次递归调用之后越来越接近这个限制条件
简单的递归
#include
int main() {
printf("hellon");
main();
}
#include
//打印数的每一位
void print(unsigned int n) {
if (n > 9) {
print(n / 10);
}
printf("%dn",n % 10);
}
void main() {
print(149);
}
内存的结构
#includeint main() { printf("hellon"); main(); }
#include//打印数的每一位 void print(unsigned int n) { if (n > 9) { print(n / 10); } printf("%dn",n % 10); } void main() { print(149); }
内存的结构
1.栈区
- 局部变量
- 函数的形参
2.堆区(动态内存分配)
3.静态区
- 全局变量
- 静态变量
注意:每一个函数调用都需要在栈区上给自己分配一个空间(栈内遵循先进后出原则)



