当前位置:网站首页>C语言学习-Day_05
C语言学习-Day_05
2022-06-27 09:49:00 【坏坏-5】
- 学习参考B站郝斌老师的视频,文章内的源码如有需要可以私信联系。
函数
- 是一个工具,不针对某一问题设计,是针对大量同类型的问题设计的
- 函数对处理的数是不一样的,但是对于数据的操作是相同的
- 什么是函数
- 逻辑上:能够完成特定功能的独立的代码块
- 物理上:能够对接受的数据进行处理,并且返回值
- 也可以不接受数据,不返回值
例:
/*函数举例*/
# include <stdio.h>
int f(void) //int表示函数返回值类型,void表示该函数不能接收数据
{
return 5; //向主调函数返回5
}
void g(void) //函数名前的void表示该函数没有返回值
{
return 3; //error,没有返回值,使用此语句会报错
}
int main(void)
{
int j = 10;
j = f(); //括号内不写值
printf("%d\n", j); //输出f函数的返回值5
j = g(); //error,因为g函数没有返回值,所以不能赋值
return 0;
}
为什么需要函数
- 对数据的操作相同,需要对多个数据进行操作,则需要使用函数来减少代码量
- 可以避免写大量重复的代码
- 有利于程序的模块化
例:现有a-f共6个变量,每个变量都有一个值,要求比较a、b,c、d,e、f之间的大小,并且输出较大的数。
/*现有a-f共6个变量,每个变量都有一个值,要求比较a、b,c、d,e、f之间的大小,并且输出较大的数*/
# include <stdio.h>
int main(void)
{
int a, b, c, d, e, f;
a = 1, b = 2, c = 4, d = -3, e = 5, f = 10; //逗号表达式
/*因为整体没有赋给变量,所以没有影响,也可以使用分号隔开 a = 1; b = 2; ... */
if (a > b)
printf("max = %d\n", a);
else
printf("max = %d\n", b);
if (c > d)
printf("max = %d\n", c);
else
printf("max = %d\n", d);
if (e > f)
printf("max = %d\n", e);
else
printf("max = %d\n", f);
return 0;
}
/*运行结果*/
max = 2
max = 4
max = 10
Press any key to continue
- 同样功能的语句,写了多次,可以使用函数,进行调用,节省代码
方法一:
/*现有a-f共6个变量,每个变量都有一个值,要求比较a、b,c、d,e、f之间的大小,并且输出较大的数*/
# include <stdio.h>
void max(int i, int j) //定义函数
{
if (i > j)
printf("max = %d\n", i);
else
printf("max = %d\n", j);
}
int main(void)
{
int a, b, c, d, e, f;
a = 1, b = 2, c = 4, d = -3, e = 5, f = 10;
max(a, b); //调用函数
max(c, d);
max(e, f);
return 0;
}
void
表示函数没有返回值,max
是函数的名字,i
、j
是形式参数,即形参- 程序执行,从
main
开始执行,执行到max(a, b);
后,认为这是调用了函数,开始检测是否定义了max
的函数
- 调用前面定义的
max
函数,然后将 a 赋值给 i,b 赋值给 j,执行函数- 函数执行完后,分配给形参的地址空间将会被释放
/*运行结果*/
max = 2
max = 4
max = 10
Press any key to continue
方法二:
/*现有a-f共6个变量,每个变量都有一个值,要求比较a、b,c、d,e、f之间的大小,并且输出较大的数*/
# include <stdio.h>
int max(int i, int j) //定义函数
{
if (i > j)
return i; //将i返回给主调函数
else
return j;
}
int main(void)
{
int a, b, c, d, e, f;
a = 1, b = 2, c = 4, d = -3, e = 5, f = 10;
printf("max = %d\n", max(a, b)); //主函数将i输出
printf("max = %d\n", max(c, d));
printf("max = %d\n", max(e, f));
return 0;
}
- 输出结果同上
- 不同点在于第一个程序中被调函数是直接将结果输出,而第二个程序中,被调函数将值返回主调函数,由主调函数进行处理
如何定义函数
- 函数定义的本质是详细描述函数之所以能够实现某个特定功能的具体方法
return 表达式;
的含义- 终止被调函数,向主调函数返回表达式的值
- 如果表达式为空,则只终止函数,不返回任何值
break
用来终止循环和switch
例:return和break的区别
/*return和break的区别*/
# include <stdio.h>
void f(void)
{
int i;
for (i = 0; i < 5; ++i)
{
printf("Bad!\n");
break; //终止的是for循环
}
return; //终止的是f函数
printf("Boy!\n"); //不会输出
}
int main(void)
{
f();
return 0;
}
/*运行结果*/
Bad!
Press any key to continue
- 函数返回值的类型也是函数的类型
- 如果函数名前的返回值类型和函数执行体中的
return 表达式
类型不同,则最终函数返回值的类型是函数名前的返回值类型
- 如果函数名前的返回值类型和函数执行体中的
- 格式
函数返回值的类型 函数的名字(函数的形参要求)
{
函数的执行体
}
例:函数返回值的类型
/*函数返回值的类型*/
# include <stdio.h>
int f()
{
return 3.5; //因为函数的返回类型是int,所以最终返回的值为3
}
int main(void)
{
double x = 5.5;
x = f(); //调用函数,数值类型以函数名前的类型为准
printf("%lf\n", x);
return 0;
}
- 函数f中的返回值是浮点型,函数名前的类型是整形
- 如果函数值类型是以
return
返回的类型为准,则返回的是3.5。如果函数值类型是以函数名前的类型为准,则函数值为3
/*运行结果*/
3.000000
Press any key to continue
函数的分类
- 有参函数和无参函数
- 有返回值和无返回值
- 库函数和自定义函数
- 值传递函数和地址传递函数
- 普通函数和主函数(main函数)
- 一个程序必须有且只有一个主函数
- 主函数可以调用普通函数,普通函数不能调用主函数
- 普通函数之间可以互相调用
- 主函数是程序的入口和出口
程序举例
例:判断一个数是否是素数
/*判断一个数是否是素数*/
# include <stdio.h>
int main(void)
{
int val;
int i;
printf("请输入需要判断的数:");
scanf("%d", &val);
for (i = 2; i < val; ++i)
{
if (val % i == 0)
break; //终止for循环
}
if (i == val)
printf("%d是素数!\n", val);
else
printf("%d不是素数!\n", val);
return 0;
}
/*运行结果*/
请输入需要判断的数:13
13是素数!
---------------------
请输入需要判断的数:9
9不是素数!
Press any key to continue
定义函数
/*判断一个数是否是素数【定义函数】*/
# include <stdio.h>
bool IsPrime(int val) //bool类型数据返回真或假
{
int i;
for (i = 2; i < val; ++i)
{
if (val % i == 0)
break;
}
if (i == val)
return true; //return会终止函数
else
return false;
}
int main(void)
{
int m;
printf("请输入需要判断的数:");
scanf("%d", &m);
if (IsPrime(m)) //判断被调函数返回值是否为真
printf("%d是素数!\n", m);
else
printf("%d不是素数!\n", m);
return 0;
}
- 输出结果同上
函数声明
- 定义函数要写在调用函数前,如果写在调用函数后,则需要写函数声明
- 函数前置声明
- 告诉编译器,即将出现的若干个字母代表的是一个函数
- 告诉编译器,若干个字母代表的函数的形参和返回值的具体情况
- 函数声明是一个语句,必须使用分号
- 对库函数的声明是通过`# inculde <库函数所在文件的文件名.h>来实现的
例:
/*函数声明*/
# include <stdio.h>
void f(void); //函数声明
int main(void)
{
f();
return 0;
}
void f(void)
{
printf("Bad Boy!\n");
}
/*运行结果*/
Bad Boy!
Press any key to continue
形参和实参
- 形参和实参的位置和个数必须一一对应,类型也必须兼容
例:
/*形参和实参*/
# include <stdio.h>
void f(int i, int j) //形参
{
printf("%d %d\n", i, j);
}
int main(void)
{
f(3, 5); //实参
return 0;
}
/*运行结果*/
3 5
Press any key to continue
合理设计函数解决实际问题
例:用户输入一个数,输出0到这个数之间的所有素数
/*用户输入一个数,输出0到这个数之间的所有素数*/
# include <stdio.h>
int main(void)
{
int i, j;
int val;
printf("请输入一个数:");
scanf("%d", &val);
printf("素数有:");
for (i = 2; i <= val; ++i)
{
for (j = 2; j < i; ++j)
{
if (0 == i % j)
break;
}
if (i == j)
printf("%d ", i);
}
printf("\n");
return 0;
}
/*运行结果*/
请输入一个数:50
素数有:2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
Press any key to continue
- 以上代码重用性不高,不容易理解,有局限性
方法二:定义函数
/*定义函数,输出指定数之间的素数*/
# include <stdio.h>
bool IsPrime(int m) //定义函数只判断数是否是素数
{
int i;
for (i = 2; i < m; ++i)
{
if (0 == m % i)
break;
}
if (i == m)
return true;
else
return false;
}
int main(void)
{
int i, val;
printf("请输入一个数:");
scanf("%d", &val);
printf("素数有:");
for (i = 2; i <= val; ++i)
{
if (IsPrime(i))
printf("%d ", i);
}
printf("\n");
return 0;
}
优化:
/*定义函数,输出指定数之间的素数*/
# include <stdio.h>
bool IsPrime(int m) //定义函数只判断数是否是素数,是则返回true,否则返回false
{
int i;
for (i = 2; i < m; ++i)
{
if (0 == m % i)
break;
}
if (i == m)
return true;
else
return false;
}
void TraverseVal(int n) //定义函数把1-n之间的所有素数输出
{
int i;
printf("素数有:");
for (i = 2; i <= n; ++i)
{
if (IsPrime(i))
printf("%d ", i);
}
printf("\n");
}
int main(void)
{
int val;
printf("请输入一个数:");
scanf("%d", &val);
TraverseVal(val); //调用函数
return 0;
}
- 函数是C语言的基本单位,类是Java,C#,C++的基本单位
常用的系统函数
double sqrt(double x); //求x的平方根
int abs(int x); //求整形x的绝对值
double fabs(double x); //求浮点数x的绝对值
变量的作用域和存储方式
- 作用域
- 全局变量
- 局部变量
- 在一个函数内部定义的变量或函数的形参
- 只能在本函数内使用
- 变量的存储方式
- 静态变量
- 自动变量
- 寄存器变量
例:
/*变量的作用域*/
# include <stdio.h>
void g()
{
printf("k = %d\n", k); //error,因为k变量被定义在了函数的后面
}
k = 3; //全局变量,之后所有的函数都可以调用
void f(int i) //局部变量,只有本函数可以调用
{
int j = 5; //局部变量
int i = 3; //error,因为形参中的变量名和函数中的变量名冲突
}
- 在一个函数内部,如果定义的局部变量名字和全局变量的名字一样,局部变量会屏蔽掉全局变量
以上内容均属原创,如有不详或错误,敬请指出。
边栏推荐
- 多個類的設計
- Some exercises about binary tree
- 通俗易懂理解樸素貝葉斯分類的拉普拉斯平滑
- Curiosity mechanism in reinforcement learning
- Une compréhension facile de la simplicité de la classification bayésienne du lissage laplacien
- 更改pip镜像源
- Use aspese slides to convert PPT to PDF
- 多个类的设计
- js的数组拼接「建议收藏」
- How do I get the STW (pause) time of a GC (garbage collector)?
猜你喜欢
随机推荐
不容置疑,这是一个绝对精心制作的项目
R语言使用econocharts包创建微观经济或宏观经济图、demand函数可视化需求曲线(demand curve)、自定义配置demand函数的参数丰富可视化效果
Markem imaje马肯依玛士喷码机维修9450E打码机维修
Design of multiple classes
R語言plotly可視化:可視化多個數據集歸一化直方圖(historgram)並在直方圖中添加密度曲線kde、設置不同的直方圖使用不同的分箱大小(bin size)、在直方圖的底部邊緣添加邊緣軸須圖
Conception de plusieurs classes
如何获取GC(垃圾回收器)的STW(暂停)时间?
使用Aspose.cells将Excel转成PDF
如何获取GC(垃圾回收器)的STW(暂停)时间?
C# Any()和AII()方法
Preliminary understanding of pytorch
2-4Kali下安装nessus
Collection framework generic LinkedList TreeSet
巴基斯坦安全部队开展反恐行动 打死7名恐怖分子
产品力对标海豹/Model 3,长安深蓝SL03预售17.98万起
小白也能看懂的网络基础 03 | OSI 模型是如何工作的(经典强推)
prometheus告警流程及相关时间参数说明
【OpenCV 例程200篇】211. 绘制垂直矩形
有关二叉树的一些练习题
Video file too large? Use ffmpeg to compress it losslessly