这是我自己整理的c语言笔记(包括链表)因为考研要用,所以整理的非常简洁。希望大家喜欢。
第三章 顺序程序设计
转义字符
ASCII表
常用的算数运算符
++i 在使用i之前,先使i的值加1
i++ i-- 在使用i之后,使i的值加1
类型转换
强制类型转换运算符:(类型名)(表达式)
数据的输入输出
printf (格式控制,输出表列);
scanf(格式控制,地址表列);
计算机向显示器输出一个字符 : putchar(c);
向计算机输入一个字符:getchar();
第四章 选择程序设计
选择结构和条件判断
if语句的一般形式: if(表达式1) 语句1
else if(表达式2) 语句2
else 语句n+1
//输入两个实数,按由小到大的顺序输出这两个数。 #include <stdio.h> int main() { float a,b,t; scanf("%f,%f",&a,&b); if(a>b) { //将a和b的值互换 t=a; a=b; b=t; } printf("%5.2f,%5.2f\n",a,b); return 0; }
条件运算符和条件表达式
max=(a>b) ? a : b; 表达式 1 ? 表达式 2 : 表达式 3
关系表达式
关系表达式的值是一个逻辑值,即“真”或“假”。
在C的逻辑运算中,以“1”代表“真”,以“0”代表“假”。
若a=3,b=2,c=1,则: d=a>b,由于a>b为真,因此关系表达式a>b的值为1,所以赋值后d的值为1。 f=a>b>c,则f的值为0。因为“>”运算符是自左至右的结合方向,先执行“a>b”得值为1, 再执行关系运算“1>c”,得值0,赋给f,所以f的值为0
逻辑运算符及其优先次序
运算符 | 含义 | 举例 | 说明 |
---|---|---|---|
! | 逻辑非(NOT) | !a | 如果a为假,则!a为真;如果a为真,则!a为假 |
&& | 逻辑与(AND) | a && b | 如果a和b都为真,则结果为真,否则为假 |
|| | 逻辑或(OR) | a || b | 如果a和b有一个以上为真,则结果为真,二者都为假时,结果为假 |
判别year表示的某一年是否闰年:(year % 4 == 0 && year % 100 != 0) ‖ year % 400 == 0;
switch语句实现多分支选择结构
switch(表达式) 花括号内是一个复合语句,内包含多个以关键字case开头的语句。
{ case后面跟一个常量(或常量表达式),它们起标号作用,用来标志一个位置。
case 常量 1 : 语句 1 执行switch语句时,先计算switch后面的“表达式”的值,然后将它与各case标号比较
case 常量 2 : 语句 2 如果与某一个case标号中的常量相同,流程就转到此case标号后面的语句。
⋮ ⋮ ⋮ 如果没有与switch表达式相匹配的case常量,流程转去执行default标号后面的语句。
case 常量 n : 语句 n
default : 语句 n+1}
//要求按照考试成绩的等级输出百分制分数段,A等为85分以上,B等为70~84分, //C等为60~69分,D等为 60分以下。成绩的等级由键盘输入。 #include <stdio.h> int main() { void action1(int,int),action2(int,int); //函数声明 char ch; int a=15,b=23; ch=getchar(); switch(ch) { case 'a': case 'A': action1(a,b);break; //调用action1函数,执行A操作 case 'b': case 'B': action2(a,b);break; //调用action2函数,执行B操作 ⋮ default: putchar('\a'); //如果输入其他字符,发出警告 } return 0; }
第五章 循环结构程序设计
while( 表达式 ) 语句
只要当循环条件表达式为真(即给定的条件成立),就执行循环体语句
//求1+2+3+…+100,即∑_(𝑛=1)^100▒𝑛 #include<stdio.h> int main() { int i=1,sum=0; //定义变量i的初值为1,sum的初值为0 while(i<=100) //当i>100,条件表达式i<=100的值为假,不执行循环体 { //循环体开始 sum=sum+i; //第1次累加后,sum的值为1 i++; //加完后,i的值加1,为下次累加做准备 } //循环体结束 printf("sum=%d\n",sum); //输出1+2+3…+100的累加和 return 0; }
用do⋯while语句实现循环
do{
语句
}while( 表达式 );
#include <stdio.h> int main() { int i=1,sum=0; do { sum=sum+i; i++; }while(i<=100); printf("sum=%d\n",sum); return 0; }
用for语句实现循环
for( 表达式 1 ;表达式 2 ;表达式 3 ){
语句}
//输入一个大于3的整数n,判定它是否为素数(prime,又称质数)。 #include <stdio.h> int main() { int n,i; printf("please enter a integer number,n=?"); scanf("%d",&n); for (i=2;i<n;i++) if(n%i==0) break; if(i<n) printf("%d is not a prime number.\n",n); else printf("%d is a prime number.\n",n); return 0; }
break语句提前终止循环
continue语句提前结束本次循环
//求Fibonacci(斐波那契)数列的前40个数 #include <stdio.h> int main() { int f1=1,f2=1,f3; int i; printf("%12d\n%12d\n",f1,f2); for(i=1; i<=38; i++) { f3=f1+f2; printf("%12d\n",f3); f1=f2; f2=f3; } return 0; }
第六章 数组处理批量数据
定义一维数组:类型说明符 数组名 [ 常量表达式 ] int a[10];
引用一维数组元素: 数组名 [ 下标 ]
//对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出。 #include<stdio.h> int main() {int i,a[10]; for(i=0; i<=9;i++) //对数组元素a[0]~a[9]赋值 a[i]=i; for(i=9;i>=0;i--) //输出a[9]~a[0]共10个数组元素 printf("%d ",a[i]); printf("\n"); return 0; }
定义二维数组: 类型说明符 数组名 [ 常量表达式 ] float pay [3] [6];
引用二维数组元素: 数组名 [ 下标 ] [ 下标 ]
//有一个3×4的矩阵,要求编程序求出其中值最大的那个元素的值,以及其所在的行号和列号。 #include <stdio.h> int main() { int i,j,row=0,colum=0,max; int a[3][4]={{1,2,3,4},{9,8,7,6},{-10,10,-5,2}}; //定义数组并赋初值 max=a[0][0]; //先认为a[0][0]最大 for(i=0;i<=2;i++) for(j=0;j<=3;j++) if(a[i][j]>max) //如果某元素大于max,就取代max的原值 { max=a[i][j]; row=i; //记下此元素的行号 colum=j; //记下此元素的列号 } printf("max=%d\nrow=%d\ncolum=%d\n",max,row,colum); return 0; }
字符数组
定义字符数组:用来存放字符数据的数组是字符数组。在字符数组中的一个元素内存放一个字符。
字符数组的初始化:对字符数组初始化,最容易理解的方式是用“初始化列表”,把各个字符依次赋给数组中各元素。
//输出一个已知的字符串。 #include <stdio.h> int main() { char c[15]={'I',' ','a','m',' ','a',' ','s','t','u','d','e','n','t','.'}; int i; for(i=0;i<15;i++) printf("%c",c[i]); printf("\n"); return 0; }
字符串和字符串结束标志:为了测定字符串的实际长度,C语言规定了一个“字符串结束标志”,以字符 ′\0′ 作为结束标志。
字符数组的输入输出:
(1) 逐个字符输入输出。用格式符“%c”输入或输出一个字符。
(2) 将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串(string)的输入输出。
scanf函数中的输入项如果是字符数组名,不要再加地址符&
因为在C语言中数组名代表该数组第一个元素的地址(或者说数组的起始地址)。
scanf("%s", &str); //str前面不应加&
使用字符串处理函数
输出字符串的函数:puts( 字符数组 )
输入字符串的函数:gets( 字符数组 )
gets(str);
字符串连接函数:strcat ( 字符数组 1, 字符数组 2)
char str1[30]={"People′s Republic of "}; char str2[]={"China"}; printf("%s", strcat(str1, str2));
字符串复制函数:strcpy ( 字符数组 1, 字符串 2)
char str1[10], str2[]="China"; strcpy(str1, str2); 或 strcpy(str1, "China");
字符串比较函数: strcmp ( 字符串 1, 字符串 2)
(1) 如果字符串1与字符串2相同,则函数值为0。
(2) 如果字符串1>字符串2,则函数值为一个正整数。
(3) 如果字符串1<字符串2,则函数值为一个负整数。
strcmp(str1, str2); strcmp("China", "Korea"); strcmp(str1, "Beijing");
测字符串长度的函数: strlen ( 字符数组 )
#include <stdio.h> #include <string.h> int main() { char str[10]="China"; printf("%d,%d\n",strlen(str),strlen("China")); }
将字符串中大写字母换成小写字母: strlwr ( 字符串 )
将字符串中小写字母换成大写字母:strupr( 字符串 )
//有3个字符串,要求找出其中“最大”者。 #include<stdio.h> #include<string.h> int main() { char str[3][20]; //定义二维字符数组 char string[20]; //定义一维字符数组,作为交换字符串时的临时字符数组 int i; for(i=0;i<3;i++) gets(str[i]); //读入3个字符串,分别给str[0],str[1],str[2] if(strcmp(str[0],str[1])>0) //若str[0]大于str[1] strcpy(string,str[0]); //把str[0]的字符串赋给字符数组string else //若str[0]小于等于str[1] strcpy(string,str[1]); //把str[1]的字符串赋给字符数组string if(strcmp(str[2],string)>0) //若str[2]大于string strcpy(string,str[2]); //把str[2]的字符串赋给字符数组string printf("\nthe largest string is:\n%s\n",string); //输出string return 0; }
//输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。 #include <stdio.h> int main() { char string[81]; int i,num=0,word=0; char c; gets(string); //输入一个字符串给字符数组string for(i=0;(c=string[i])!='\0';i++) //只要字符不是'\0'就循环 if(c==' ') word=0; //若是空格字符,使word置0 else if(word==0) //如果不是空格字符且word原值为0 { word=1; //使word置1 num++; //num累加1,表示增加一个单词 } printf("There are %d words in this line.\n",num); //输出单词数 return 0; }
排序
//选择排序 #include <stdio.h> int main() { int a[10], i, j, k, x; for (i = 0; i < 10; i++) scanf("%d", &a[i]); for (i = 0; i < 9; i++) { k = i; for (j = i + 1; j < 10; j++) if (a[j] < a[k]) k = j; x = a[i]; a[i] = a[k]; a[k] = x; } } for (i = 0; i < 10; i++) printf("%d ", a[i]); return 0; }
//冒泡排序 #include <stdio.h> int main() { int a[10], i, j, t; for (i = 0; i < 10; i++) //输入10个整数 scanf("%d", &a[i]); for (i = 1; i < 10; i++) //趟数,共10-1趟 { for (j = 0; j < 10 - i; j++) //实现一次冒泡操作 if (a[j] > a[j + 1]) //交换a[j]和a[j+1] { t = a[j]; a[j] = a[j + 1]; a[j + 1] = t; } }//输出排好序的数据 printf("the sorted numbers:\n"); for (i = 0; i < 10; i++) printf("%d ", a[i]); return 0; }
//插入排序 #include<stdio.h> int main() { int a[10]; int cur; int i, j; for (i = 0; i < 10; i++) //输入NUM个整数 scanf("%d", &a[i]); for (i = 1; i < 10; i++) { cur = a[i]; //待排序元素 for (j = i - 1; j >= 0 && a[j] > cur; j--) { a[j + 1] = a[j]; } a[j + 1] = cur; } for (i = 0; i < 10; i++) { printf("%d ", a[i]); } return 0; }
第七章 用函数实现模块化程序设计
定义函数 定义有参函数
定义无参函数:类型名 函数名() 类型名 函数名 ( 形式参数表列 )
{ {
函数体 函数体
} }
函数调用的形式
函数名 ( 实参表列 )
print_star(); //调用无参函数 c=max(a,b); //调用有参函数
形式参数和实际参数
在定义函数时函数名后面括号中的变量名称为“形式参数”(简称“形参”)或“虚拟参数”。
在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”(简称“实参”)。 实际参数可以是常量、变量或表达式,但要求它们有确定的值。
//输入两个整数,要求输出其中值较大者。要求用函数来找到大数。 #include <stdio.h> int main() { int max(int x,int y); //对max函数的声明 int a,b,c; printf("please enter two integer numbers:"); //提示输入数据 scanf("%d,%d",&a,&b); //输入两个整数 c=max(a,b); //调用max函数,有两个实参。大数赋给变量c printf("max is %d\n",c); //输出大数c return 0; } int max(int x,int y) //定义max函数,有两个参数 { int z; //定义临时变量z z=x>y?x:y; //把x和y中大者赋给z return(z); //把z作为max函数的值带回main函数 }
函数的嵌套调用
输入4个整数,找出其中最大的数。用函数的嵌套调用来处理。 #include <stdio.h> int main() { int max4(int a,int b,int c,int d); //对max4的函数声明 int a,b,c,d,max; printf("Please enter 4 interger numbers:"); //提示输入4个数 scanf("%d %d %d %d",&a,&b,&c,&d); //输入4个数 max=max4(a,b,c,d); //调用max4函数,得到4个数中的最大者 printf("max=%d \n",max); //输出4个数中的最大者 return 0; } int max4(int a,int b,int c,int d) //定义max4函数 { int max2(int a,int b); //对max2的函数声明 int m; m=max2(a,b); //调用max2函数,得到a和b中的大者,放在m中 m=max2(m,c);//调用max2函数,得到a,b,c中的大者,放在m中 m=max2(m,d);//调用max2函数,得到a,b,c,d中的大者,放在m中 return(m); //把m作为函数值带回main函数 } int max2(int a,int b) //定义max2函数 { if(a>=b) return a; //若a≥b,将a作为函数返回值 else return b; //若a<b,将b作为函数返回值 }
函数的递归调用
在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。
int f(int x) { int y,z; z=f(y); //在执行f函数的过程中又要调用f函数 return (2*z); }
//有5个学生坐在一起,问第5个学生多少岁,他说比第4个学生大2岁。问第4个学生岁数,他说比第3个学生大2岁。问第3个学生, //又说比第2个学生大2岁。问第2个学生,说比第1个学生大2岁。最后问第1个学生,他说是10岁。请问第5个学生多大。 #include <stdio.h> int main() { int age(int n); //对age函数的声明 printf("NO.5,age:%d\n",age(5)); //输出第5个学生的年龄 return 0; } int age(int n) //定义递归函数 { int c; //c用作存放函数的返回值的变量 if(n==1) //如果n等于1 c=10; //年龄为10 else //如果n不等于1 c=age(n-1)+2; //年龄是前一个学生的年龄加2(如第4个学生年龄是第3个学生年龄加2) return(c); //返回年龄 }
//用递归方法求n!。 #include <stdio.h> int main() { int fac(int n); //fac函数声明 int n; int y; printf("input an integer number:"); scanf("%d",&n); //输入要求阶乘的数 y=fac(n); printf("%d!=%d\n",n,y); return 0; } int fac(int n) //定义fac函数 { int f; if(n<0) //n不能小于0 printf("n<0,data error!"); else if(n==0||n==1) //n=0或,1时n!=1 f=1; //递归终止条件 else f=fac(n-1)*n; //n>1时,n!=n*(n-1) return(f); }
/*Hanoi(汉诺)塔问题。古代有一个梵塔,塔内有3个座A,B,C。开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个老和尚想把这64个盘子从A座移到C座,但规定每次只允许移动一个盘,且在移动过程中在3个座上都始终保持大盘在下,小盘在上。在移动过程中可以利用B座。要求编程序输出移动盘子的步骤。*/ #include <stdio.h> int main() { void hanoi(int n,char one,char two,char three); //对hanoi函数的声明 int m; printf("input the number of diskes:"); scanf("%d",&m); printf("The step to move %d diskes:\n",m); hanoi(m,'A','B','C'); } void hanoi(int n,char one,char two,char three) //定义hanoi函数 //将n个盘从one座借助two座,移到three座 { void move(char x,char y); //对move函数的声明 if(n==1) move(one,three); else { hanoi(n-1,one,three,two); move(one,three); hanoi(n-1,two,one,three); } } void move(char x,char y) //定义move函数 { printf("%c->%c\n",x,y); }
数组作为函数参数
数组元素作函数实参
//输入10个数,要求输出其中值最大的元素和该数是第几个数。 #include <stdio.h> int main() { int max(int x,int y); //函数声明 int a[10],m,n,i; printf("enter 10 integer numbers:"); for(i=0;i<10;i++) //输入10个数给a[0]~a[9] scanf("%d",&a[i]); printf("\n"); for(i=1,m=a[0],n=0;i<10;i++) { if(max(m,a[i])>m) //若max函数返回的值大于m { m=max(m,a[i]); //max函数返回的值取代m原值 n=i; //把此数组元素的序号记下来,放在n中 } } printf("The largest number is %d\nit is the %dth number.\n",m,n+1); } int max(int x,int y) //定义max函数 { return(x>y?x:y); //返回x和y中的大者 }
一维数组名作函数参数
//有一个一维数组score,内放10个学生成绩,求平均成绩。 #include <stdio.h> int main() { float average(float array[10]); //函数声明 float score[10],aver; int i; printf("input 10 scores:\n"); for(i=0;i<10;i++) scanf("%f",&score[i]); printf("\n"); aver=average(score); //调用average函数 printf("average score is %5.2f\n",aver); return 0; } float average(float array[10]) //定义average函数 { int i; float aver,sum=array[0]; for(i=1;i<10;i++) sum=sum+array[i]; //累加学生成绩 aver=sum/10; return(aver); }
多维数组名作函数参数
//有一个3×4的矩阵,求所有元素中的最大值。 #include <stdio.h> int main() { int max_value(int array[][4]); //函数声明 int a[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}}; //对数组元素赋初值 printf("Max value is %d\n",max_value(a)); //max_value(a)为函数调用 return 0; } int max_value(int array[][4]) //函数定义 { int i,j,max; max=array[0][0]; for(i=0;i<3;i++) for(j=0;j<4;j++) if(array[i][j]>max) max=array[i][j]; //把大者放在max中 return(max); }
第八章 善于利用指针
指针变量
//通过指针变量访问整型变量。 #include <stdio.h> int main() { int a=100,b=10; //定义整型变量a,b,并初始化 int *pointer_1,*pointer_2; //定义指向整型数据的指针变量pointer_1, pointer_2 pointer_1=&a; //把变量a的地址赋给指针变量pointer_1 pointer_2=&b; //把变量b的地址赋给指针变量pointer_2 printf("a=%d,b=%d\n",a,b); //输出变量a和b的值 printf("*pointer_1=%d,*pointer_2=%d\n",*pointer_1,*pointer_2); return 0; }
定义指针变量:类型名 *指针变量名; int *pointer_1, *pointer_2;
引用指针变量:
int a, *p; p=&a; //把a的地址赋给指针变量p ① printf("%d",*p); //以整数形式输出指针变量p所指向的变量的值,即a的值 ② *p=1; //将整数1赋给p当前所指向的变量,由于p指向变量a,相当于把1赋给a,即a=1 ② printf("%o",p); //以八进制形式输出指针变量p的值,由于p指向a,相当于输出a的地址,即&a ③
要熟练掌握两个有关的运算符:
(1) &取地址运算符。&a是变量a的地址。
(2) * 指针运算符(或称“间接访问”运算符),*p代表指针变量p指向的对象。
//输入a和b两个整数,按先大后小的顺序输出a和b。 #include <stdio.h> int main() { int *p1,*p2,*p,a,b; //p1,p2的类型是int *类型 printf("please enter two integer numbers:"); scanf("%d,%d",&a,&b); //输入两个整数 p1=&a; //使p1指向变量a p2=&b; //使p2指向变量b if(a<b) //如果a<b { p=p1;p1=p2;p2=p;} //使p1与p2的值互换 printf("a=%d,b=%d\n",a,b); //输出a,b printf("max=%d,min=%d\n",*p1,*p2); //输出p1和p2所指向的变量的值 return 0; }
通过指针引用数组
//有一个整型数组a,有10个元素,要求输出数组中的全部元素。 #include <stdio.h> int main() { int a[10]; int *p,i; printf("please enter 10 integer numbers:"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(p=a;p<(a+10);p++) printf("%d ",*p); //用指针指向当前的数组元素 printf("\n"); return 0; }
*通过指针引用多维数组
//有一个3×4的二维数组,要求用指向元素的指针变量输出二维数组各元素的值。 #include <stdio.h> int main() { int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int *p; //p是int *型指针变量 for(p=a[0];p<a[0]+12;p++) //使p依次指向下一个元素 { if((p-a[0])%4==0) printf("\n"); //p移动4次后换行 printf("%4d",*p); //输出p指向的元素的值 } printf("\n"); return 0; }
通过指针引用字符串
字符串的引用方式:
(1)用字符数组存放一个字符串,可以通过数组名和下标引用字符串中一个字符,也可以通过数组名和格式声明“%s”输出该字符串。
(2)用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。
//定义一个字符数组,在其中存放字符串″I love China!″,输出该字符串和第8个字符。 #include <stdio.h> int main() { char string[]="I love China!"; //定义字符数组sting printf("%s\n",string); //用%s格式声明输出string,可以输出整个字符串 printf("%c\n",string[7]); //用%c格式输出一个字符数组元素 return 0; }
第九章 用户自己建立数据类型
定义和使用结构体变量
建立结构体类型: struct 结构体名
{ 成员表列 };
struct Date //声明一个结构体类型 struct Date { int month; //月 int day; //日 int year; //年 }; struct Student //声明一个结构体类型 struct Student { int num; struct Date birthday; //成员birthday属于struct Date类型 };
结构体变量的初始化和引用
//把一个学生的信息(包括学号、姓名、性别、住址)放在一个结构体变量中,然后输出这个学生的信息。 #include <stdio.h> int main() { struct Student //声明结构体类型struct Student { long int num; //以下4行为结构体的成员 char name[20]; char sex; char addr[20]; }a={10101,"Li Lin",'M',"123 Beijing Road"}; //定义结构体变量a并初始化 printf("NO.:%ld\nname:%s\nsex:%c\naddress:%s\n",a.num,a.name,a.sex,a.addr); return 0; }
使用结构体数组
//有3个候选人,每个选民只能投票选一人,要求编一个统计选票的程序,先后输入被选人的名字,最后输出各人得票结果。 #include <string.h> #include <stdio.h> struct Person //声明结构体类型struct Person { char name[20]; //候选人姓名 int count; //候选人得票数 }leader[3]={"Li",0,"Zhang",0,"Sun",0}; //定义结构体数组并初始化 int main() { int i,j; char leader_name[20]; //定义字符数组 for(i=1;i<=10;i++) { scanf("%s",leader_name); //输入所选的候选人姓名 for(j=0;j<3;j++) if(strcmp(leader_name,leader[j].name)==0) leader[j].count++; } printf("\nResult:\n"); for(i=0;i<3;i++) printf("%5s:%d\n",leader[i].name,leader[i].count); return 0; }