C语言----函数(1)https://developer.aliyun.com/article/1544258
7.嵌套调用和链式访问
//假设我们某年某月有多少天 //只有闰年的2月有29天,需要对y判断是否是闰年 //函数只有两种返回 //是闰年 //不是闰年 int is_leap_year(int y) { if(((y%4==0)&&(y%100!=0)||(y%400==0)))//闰年的判断, return 1;//如果是闰年就返回1 else return 0;//不是闰年就返回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 1 2 3 4 5 6 7 8 9 10 11 下标 int day = days[m]; if (is_leap_year(y) == 1 && m==2)//如果是闰年就返回一,表示为真的,并且m是二月 { day++;//闰年二月的时候,天数+1,为29天 } return day;//如果不是二月就返回day } int main() { int month = 0; int year = 0; scanf("%d %d", &year, & month); //计算某年某月有多少天 int day =get_days_of_month(year, month);//这个函数传了年和月 printf("%d\n", day); return 0; } //main函数调用get_days_of_month去计算某年某月有多少天 //get_days_of_month这个函数内部又要通过is_leap_year判断输入的数是否是闰年 //17行的==1可以不写 做出改变,用布尔类型来做: bool is_leap_year(int y) //布尔类型,判断真假 { if (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)))//闰年的判断, return true;//如果是闰年就返回true else return false;//不是闰年就返回false }
所谓链式访问就是将一个函数的返回值作为另一个函数的参数,像链条一样将函数串起来就是函数的链式访问 int main() { //printf("%d", printf("%d", printf("%d ", 43)));//输出结果是4321 /*int r = printf("hehe"); printf("%d\n", r);*///输出结果是hehe4,返回的是4个字符 printf("%d", printf("%d ", printf("%d ", 43))); //printf("%d", 43)这个打印出来的是43,打印两个字符返回值是2 //printf("%d", printf("%d", 2)); //printf("%d", 2) 再屏幕上打印2,打印一个字符返回值是1 //printf("%d", 1);打印就是1 //所以最终的结果是4321 /*先打印43,再打印2,最后打印1*/ //如果在中间和后面的两个printf里面的%d后面添加一个空格,输出结果就不一样了,变为43 3 2 //这种情况的话最先的打印是43加一个空格,返回3个字符 //然后第二次打印就是打印3和一个空格,返回2个字符 //然后就变成了printf("%d",2),打印2 //最终结果就变成43 3 2 return 0; }
8.函数的声明和定义
函数或者变量都要满足,先声明后使用
声明后面要加分号,定义后面不用加分号
//函数的定义是一种特殊的声明 /*int is_leap_year(int y);*///函数的声明,只要函数提前声明了,不管函数定义在前面还是后面,都能使用 int is_leap_year(int );//函数声明的另一种写法,在声明内容中形参的名字是可以不用写的 int main() { int year = 0; scanf("%d", year); if (is_leap_year(year)==true)//函数的调用 { printf("%d 是闰年", year); } else { printf("%d 不是闰年", year); } return 0; } //函数的定义 int is_leap_year(int y) //布尔类型,判断真假 { if (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)))//闰年的判断, return 1;//如果是闰年就返回true else return 0;//不是闰年就返回false }
新创建一个源文件add.c 新创建一个头文件add.h 源文件add.c放函数的定义实现 头文件add.h放函数的声明 如果要使用的话,就写出头文件打代码 #include "add.h" 写出这行代码,头文件就能正常使用了 这样就把函数的声明和定义拆散了,函数定义放在.c文件 函数声明放在头文件 我们要把add.h和add.c当做一个模块,只要想使用这个模块,包含头文件即可
把大型复杂的程序,拆分成多个文件的好处
1.团队协作
2.代码模块化,逻辑更加清晰
3.代码的隐藏
局部变量的作用域就是变量所在的局部范围 //int main() //{ // { // int a = 100;//定义的a只在这个括号内使用,出了这个括号就用不了了 // printf("1 a=%d\n", a); // } // //printf("2 a=%d\n", a); // // // return 0; //} int main() { int a = 100;//把a的定义放在外围的括号内处于这个括号的打印都能用 { //定义的a只在这个括号内使用,出了这个括号就用不了了 printf("1 a=%d\n", a); } printf("2 a=%d\n", a); return 0; }
全局变量的作用域是整个工程 int a = 100; int main() { { printf("1 a=%d\n", a); } printf("2 a=%d\n", a); return 0; }
static是静态的意思,可以用来: 1.修饰局部变量 2.修饰全局变量 3.修饰函数 extem是用来声明外部符号的 ertem: 在ass.c定义int a = 100;这就是定义的全局变量 //extern是用来声明外部符号的 笔记.c extern int a;//变量的声明 int main() { { printf("1 a=%d\n", a); } printf("2 a=%d\n", a); return 0; } add.c int a = 100; extern是声明外部符号的,只要这个符号是来自外部的,只要用extern 就可以调用了 声明一各变量的方式,知道类型和名字就行了
//void test()//进入函数 //{ // int a = 1;/*将a赋值为1局部变量*/ // a++;//a直接新创建一个值 // printf("%d", a); //} // //int main5() //{ // for (int i = 0; i < 5; i++)//i从0开始,循环5次 // { // test(); // } // return 0; //} //为什么这个函数输出是2 //因为每次调用test函数的时候,我们就会定义一次a并赋值为1,然后就是2, //第二轮循环也一样,在每个循环的开始a都是以1出现的,所以最后打印的结果就是5个2 void test()//进入函数 { static int a = 1;//在局部变量前面加static\ //输出结果截然不同,结果为:23456 a++; printf("%d", a); } int main() { for (int i = 0; i < 5; i++)//i从0开始,循环5次 { test(); } return 0; } //为何在局部变量前面添加static后,结果变得不一样了 //static修饰局部变量改变了变量的声明周期 //在test函数中没有static的话,局部变量 是进入这个函数开始,出去这个函数生命周期结束 //没有被static修饰,局部变量的位置是在栈区的,进入这个函数生成,出去这个函数销毁 //被static修饰修饰的变量就不放在栈区了,就放在静态区了,static修饰修饰的变量叫静态变量 //存储在静态区的变量和全局变量一样的,声明周期就和程序的生命周期一样了 //但是本代码中的a的作用域不变, //ststic修饰的变量,在第二轮循环的时候,使用的变量就是上一次留下来的,而不是新建的变量 //如何使用static去修饰变量 //:未来一个变量出了函数,我们还想保留值,等下次进入函数继续使用,就可以使用static去修饰这个变量
//如何使用static去修饰局部变量
//:未来一个变量出了函数,我们还想保留值,等下次进入函数继续使用,就可以使用static去修饰这个变量
// 将全局变量放到其他文件 //函数要先声明再使用,变量也一样 //一个全局变量,要想在其他文件中使用,只需要用extern声明外部符号,就可以使用了 //全局变量是默认带有外部链接属性的,只要用extern引用就行了 extern int g_val;//对变量进行声明 int main() { printf("%d\n", g_val); return 0; } //但是如果想引用其他文件夹的全局变量,但是这个全局变量被static修饰了, // 那么这个全局变量就不能被引用 //static修饰全局变量的时候,改变了全局变量的链接属性 //使得外部链接属性,变成了内部链接属性 //这种变量只能在自己所在的.c文件中使用,其他的.c文件中无法使用 //使用建议:如果一个全局变量,只想在所在的源文件内部使用,不想被其他文件发现, // 就可以使用static修饰
//函数在另一个文件 //extern Add(int, int);//声明外部符号就可以使用了 //函数也具有外部链接属性的,只要在其他的.c文件中正确的声明,也可以直接使用 int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); int c = Add(a, b); printf("c=%d\n", c); return 0; } //Add(int x, int y)//static修饰函数,让函数外部链接属性变为内部链接属性 // 只能在自己所在的.c文件中使用,其他.c文件中无法使用 //{ // return x + y; //}