网站备案表是什么首页关键词怎么排名靠前
一.前言
C 语⾔强调模块化编程,这⾥所说的模块就是函数,即把每⼀个独⽴的功能均抽象为⼀个函数来实现。从⼀定意义上讲,C 语⾔就是由⼀系列函数串组成的。 我们之前把所有代码都写在 main 函数中,这样虽然程序的功能正常实现,但显得杂乱⽆章,代码可读性、可维护性较差。学完本节之后,应把每个具体的独⽴功能单位均抽象为⼀个函数,在 main 函数中 调⽤各个函数。
1.概念:
函数是⼀系列 C 语⾔语句的集合, 为了完成某个可能会重复使⽤的功能, ⽽封装起来的代码。
设计的好处: 实现模块化的编程思想,提⾼程序的可读性。
函数设计要求: ⻅名知意。
示例代码:
2.使用方法:
方法1:先声明在定义
返回值类型 函数名(类型 参数1,类型 参数2….); // 函数的声明int main(){函数名(参数1,参数2,参数3); // 函数的调用return 0;}返回值类型 函数名(类型 参数1,类型 参数2….) // 函数的定义
{C语⾔代码;return 数据;
}
示例代码:
#include<stdio.h>
void printf_star();
/// *
/// **
/// ***
int main() // 入口
{for(int k = 1; k <= 3; k++){printf_star(); // 函数的调用}return 0;
} /// void表示返回空void printf_star() // 函数的定义{for(int i = 1; i <= 3; i++) // i代表行数{for(int j = 1;j <= i; j++) // 每行输出的星星个数{printf("*");}printf("\n");}return 0;}
练习:
1. 设计⼀个 void do_sum() 函数,要求函数内部⽆参数和返回值,内部定义⼀个变量 int m, 要求⽤户从键盘输⼊⼀个数据赋值给 m 。
判断 m 的值 , 若是 m 为奇数,输出 1 + 3 + 5 + 7 + 9 +...+m 的和 . 若是 m 为偶数,输出 0 + 2 + 4 + 6 + 8 +...+m 的和 .
#include <stdio.h>void do_sum() {int m;printf("请输入一个整数:");scanf("%d", &m);int sum = 0;if (m % 2 != 0) {// 计算奇数和 1+3+5+...+mfor (int i = 1; i <= m; i += 2) {sum += i;}} else {// 计算偶数和 0+2+4+...+mfor (int i = 0; i <= m; i += 2) {sum += i;}}printf("计算结果为:%d\n", sum);
}int main() {do_sum();return 0;
}
2. 设计⼀个 void do_Result() 函数,要求函数内部定义 int a,b 两个变量,然后从键盘输⼊ 2 个整数赋值给 a,b ,并输出 (a + b) / 2 的值。
#include <stdio.h>void do_Result() {int a, b;printf("请输入两个整数(用空格分隔):");scanf("%d %d", &a, &b);int result = (a + b) / 2;printf("计算结果为:%d\n", result);
}int main() {do_Result();return 0;
}
二.全局 静态 局部变量
1.全局变量:
全局变量: 在函数外部定义的变量,我们叫做全局变量.特点:(1) 在本⽂件中的任何函数中都可以使⽤。 ----作⽤域(2) 在定义变量的时候,系统会申请内存空间,main()函数结束的时候,系统会回收全局变量对应的内存空间. ----⽣命周期(3) 全局变量未初始化,值默认为0
2.局部变量:
局部变量: 在函数内部定义的变量,我们叫做局部变量。特点:(1) 只能在定义它的那个函数内部使⽤,其他位置不能使⽤。---作⽤域(2) 调⽤函数时,运⾏在定义变量代码的时候,系统会申请内存空间, 当定义该变量的函数调⽤结束后,系统会回收局部变量对应的内存空间. ----⽣命周期(3) 局部变量未初始化,值默认为随机值。
示例代码:
#include<stdio.h>int global = 20;void do_global(){global ++;printf("global = %d\n",global);}void do_local(){int t = 10;t++;printf("t = %d\n", t);return ;}int main()
{do_global();do_global();do_global();printf("======================\n");global++;printf("g = %d\n",global);do_local();do_local();do_local();return 0;
}
3.静态局部变量
静态局部变量格式: static 数据类型 变量名;static int c;特点:
(1)静态局部变量,可以改变原来变量的⽣命周期,当定义该变量的函数调⽤结束后,系统不会回收对应的内存空间,当main()函数结束后, 内存空间才会被回收.(2)只能在定义它的那个函数内部使⽤,其他位置不能使⽤。---作⽤域(3)静态局部变量未初始化,值默认为0
示例代码:
#include <stdio.h>void do_local(){static int t = 10;t++;printf("t = %d\n",t);}int main(){do_local();do_local();do_local();return 0;}
练习:
定义全局变量 global_data = 0; 设计⽆参数的函数 global_calc() ,在这个函数内部 要求⽤户从键盘输⼊⼀个数据赋值给 global_data, 然后要求 该函数输出,从 1~global_data 之间所有能被 7 整除的数据。 main 函数来调⽤以下 global_calc() 这个函数。
#include <stdio.h>int global_data = 0; // 定义全局变量void global_calc() {printf("请输入一个正整数:");scanf("%d", &global_data);if(global_data < 7) {printf("没有符合条件的数字\n");return;}printf("能被7整除的数字:\n");for(int i = 7; i <= global_data; i++) {if(i % 7 == 0) {printf("%d ", i);}}printf("\n");
}int main() {global_calc();return 0;
}
三.函数传参之值传递
本质: 函数传参的本质, 变量之间的赋值操作。
功能 :在传递变量中保存的数据。核⼼思想是传递什么样⼦类型的变量。
在接收的位置,就定义什么样类型的变量来接受。
示例代码:
#include<stdio.h>int do_calc(const int x,const int y){int sum = 0;printf("x = %d y = %d\n", x,y);sum = x + y;return sum;}
int main()
{int a = 0,b = 0;int t = 0;printf("please input two data :");scanf("%d%d",&a,&b);t = do_calc(a,b);printf("a + b =%d\n", t);t = t*100-8;printf("expression result = %d\n",t);return 0;
}
运行结果:
四.函数传参之地址传递
功能:我们在使⽤函数传参的时候,除了传递普通的变量外,在某些时刻不得不传递变量的地址。
传递变量的地址,我们在使⽤的时候,就只能通过指针来接收了。好处:传递变量的地址,通过指针接收,可⽤通过指针修改原变量的值。
示例代码:
#include<stdio.h>void change_value(int *x, int*y)
{int t;t = *x;*x = *y;*y = t;return ;
}void do_calc(int x, int y,int *m,int *n)
{int sum1 = 0,sum2 = 0;sum1 = x+y;sum2 = x-y;*m = sum1;*n = sum2;return ;
}int main()
{int a = 0,b = 0;int ret1 = 0,ret2 = 0;int t = 0;printf("please input two data :");scanf("%d%d",&a,&b);do_calc(a,b,&ret1,&ret2);printf("a+b=%d\n",ret1);printf("a-b=%d\n",ret2);return 0;
}
练习:
1.main() 函数定义 4 个变量, int a,b,max_value,sum. 要求⽤户从键盘输⼊2 个数据赋值给 a和b
2. 设计⼀个叫做 calc_data() 函数,⾃定义返回值和参数,要求该函数中 求出 a 和 b 中的最⼤值,函数调⽤结束后,要求给 main 函数 max_value 存储的 是两个数中较⼤的值。在求两个数的和,要求给 main 函数 sunm 存储的两个 数据的和。
3. 在 main 函数中打印 max_value 和 sum 的值。
#include <stdio.h>void calc_data(int x, int y, int *max_ptr, int *sum_ptr) {*max_ptr = (x > y) ? x : y;*sum_ptr = x + y;
}int main() {int a, b, max_value, sum;printf("请输入两个整数:");scanf("%d %d", &a, &b);calc_data(a, b, &max_value, &sum);printf("最大值:%d\n", max_value);printf("两数之和:%d\n", sum);return 0;
}
五.. 函数传参之数组
本质 :函数传参的本质是变量间的赋值操作,数组名本质是⾸元素的地址,传递数组的⾸地址,我 们定义指针来接收接⼝。
示例代码:
#include<stdio.h>void input_array(int *p,const int plen){int i = 0;printf("please input %d data:",plen);for(i = 0; i < plen; i++){scanf("%d",&p[i]);}}void output_array(int *p, const int plen){int i = 0;for(i = 0; i < plen; i++){printf("%d\n",&p[i]);}}int main()
{int a[5] = {0};int len = sizeof(a) / sizeof(a[0]);input_array(a,len);output_array(a,len);return 0;
}
六.字符串相关操作函数1
1.strcpy ---- 字符串拷贝函数
头文件: #include <string.h>strcpy (char dest[], char src[]) ---------string copy功能:把src数组中'\0'之前的所有字符,连同'\0'一起拷贝到dest中。要求在定义dest时要足够大参数:dest--------目标数组src --------源数组---------[数组首地址或字符串]例如:char buf [20] = {0};strcpy(buf,"hello");printf("buf = %s\n", buf);
代码示例:
#include<stdio.h>
#include<string.h>int main()
{char buf[20] = {'h','e','l','l','o','\0'};int i = 0;strcpy(buf,"QQ");for(i = 0; i < 20; i++){printf("%c: %d\n",buf[i],buf[i]);} printf("buf = %s\n",buf);return 0;
}
2.strcat
头⽂件: #include <string.h>strcat(char dest[], char src[]);功能:把src数组'\0'之前的字符串追加到dest字符串后,若是dest中有'\0',会把dest中的'\0'给覆盖掉,然后组成的dest字符串会重新添加'\0'参数:例如:@ dest ⽬标数组@ src 源数组 [字符数组或字符串]char buf[] = "hello";strcat(buf," world");
代码示例:
#include<stdio.h>
#include<string.h>int main()
{char word[20];char explain[20];char sql[50];printf("please input you select word:");gets(word);printf("please input word explain:");gets(explain);strcpy(sql,word);strcat(sql,explain);printf("%s\n",sql);return 0;
}
七.字符串相关操作函数 2
1.strlen字符串长度计算函数--------不算\0
头文件: #include <stdio.h>int strlen(const char s[]);功能:计算s数组中第一个'\0'前字符的个数,并返回参数:@ s 目标数组,存放字符串
返回值:返回计算的字符个数例如:char buf[] = "hello";int len = strlen(buf);printf("len = %d\n",len);
代码示例:
2.strcmp
头文件:#include <string.h>int strcmp(char s1[], char s2[]);功能: 对s1和s2字符串中的每个字符逐个⽐较若是s1中某个字符>s2中的某个字符,则返回⼤于0的数。
若是s1中某个字符<s2中的某个字符,则返回⼩于0的数。若是当前s1和s2的字符相等,则⽐较后⼀个字符。若是完全相等,返回0参数:@ 待⽐较的数组s1 [字符串或字符数组]@ 待⽐较的数组s2 [字符串或字符数组]返回值:
在gcc的32bit编译器下,返回如下值:若是s1 > s2 ,返回1若是s1 == s2,返回0若是s1 < s2 ,返回-1char buf1[] = "hello";
char buf2[] = "heltt";
ret = strcmp(buf1,buf2);
示例代码:
#include <stdio.h>
#include <string.h>
int main()
{char buf1[20];char buf2[20];int ret = 0;printf("please input string buf1 : ");gets(buf1);printf("please input string buf2 : ");gets(buf2);ret = strcmp(buf1,buf2);printf("ret = %d\n",ret);if(ret > 0){printf("buf1 > buf2"); }else if(ret == 0){printf("buf1 == buf2"); }else if(ret < 0){printf("buf1 < buf2"); }putchar('\n');return 0;
}
运行结果:
练习:
char buf[] = "I Love China";
(1) 设计⼀个 count_uppercase_character() 函数,⾃⼰定义参数和返回值,要求 统计上述数组中⼤写字符的个数。
(2) 调⽤⾃⼰设计的函数,并输出。
代码示例:
#include <stdio.h>
#include <ctype.h>// 统计大写字母数量的函数
int count_uppercase_character(const char *str) {int count = 0;while (*str) {if (isupper(*str)) {count++;}str++;}return count;
}int main() {char buf[] = "I Love China";int result = count_uppercase_character(buf);printf("大写字母数量:%d\n", result); // 输出:3return 0;
}
八.指针函数
本质:是⼀个函数,只不过返回值是⼀个地址。思考:如何定义⼀个指针函数?返回值类型 * 函数名称 (类型 1 参数 1, 类型 2 参数 2 ,…);例如:
int * fun (int a, int b);(也就是说,指针函数其实和普通的函数⼀样的,只不过返回值是⼀个指针类型。
并且它必须⽤同类型的指针变量来接受)
练习:
(1) 要求⼤家是设计⼀个 design_arary() 函数 , ⾃⼰定义返回值和参数。 要求 design_array() 函数中定义⼀个 ,static char a[100] = {0};, 然后 把数组⾸地址和⻓度返回。
(2) 设计⼀个 input_array() 函数,⾃定义返回和参数,要求⽤户从键盘 输⼊任意的字符串,存放到 a 数组中
(3) 设计⼀个 output_array() 函数,要求输出 a 数组中的每个⼀字符, 以空格作为区分 . w u h a n s h a n g h a i
(4) 设计⼀个 cout_space() 函数,⾃定义返回和参数,要求⽤户统计数组 a 中⽤户 输⼊的空格个数,并返回值给 main 函数。
(5)main ()函数调⽤以上函数,并输出空格个数。
代码示例:
#include <stdio.h>
#include <string.h>// (1) 定义静态数组并返回信息
char* design_array(int *length) {static char a[100] = {0};*length = 100;return a;
}// (2) 输入字符串到数组
void input_array(char *arr) {printf("请输入字符串:");fgets(arr, 100, stdin);arr[strcspn(arr, "\n")] = '\0'; // 去除换行符
}// (3) 输出字符用空格分隔
void output_array(const char *arr) {for(int i = 0; arr[i] != '\0'; i++) {printf("%c ", arr[i]);}printf("\n");
}// (4) 统计空格数量
int cout_space(const char *arr) {int count = 0;for(int i = 0; arr[i] != '\0'; i++) {if(arr[i] == ' ') count++;}return count;
}int main() {int len;char *arr = design_array(&len);input_array(arr);printf("\n字符输出:");output_array(arr);int spaces = cout_space(arr);printf("空格数量:%d\n", spaces);return 0;
}
九.函数指针
1.方法1
函数指针:本质是⼀个指针,只不过使⽤来函数的地址的。 通过函数指针来调⽤,我们需要的函数。数据类型(*指针变量名)(类型1 参数1,类型2 参数2...); 注:(1)函数名代表函数的⾸地址(2)上述中的参数1,参数2.。。等可省略例如:
int (*funp)(int ,int) = add; add(10,20);
funp(10,20);
#include<stdio.h>int add(int a,int b)
{return a + b;
}/// 函数名就代表函数的地址
int sub(int a,int b)
{return a - b;
}int main(int argc,const char*argv[])
{int ret = 0;ret = add(10,20);printf("a+b=%d\n",ret);printf("add=%p\n",add);printf("=============\n");int(*funp)(int , int) = add;printf("funp = %p\n",funp);ret = funp(10,20);printf("a+b=%d\n",ret);funp = sub;printf("a-b=%d\n",ret);return 0;
}
2.方法2
概念:
回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的地址作为参数传递给另⼀个函数,在另⼀个函数中通过指针来接收 , 通过指针来调⽤其函数,我们就说这是回调函数。
#include <stdio.h>int add(int a,int b){return a + b;}int sub(int a,int b){return a - b;}int calc(int a,int b,int (*pfun)(int,int)){int result;result = pfun(a,b);return result;}int main(){int result = 0;result = calc(20,10,add)printf("a + b = %d\n",result);result = calc(20,10,sub)printf("a - b = %d\n",result);return 0;}