(一)数据
1.常量和变量
2.数据类型
(二)运算符
运算符优先级排序:
!非 > 算术运算符 > 关系运算符 > &&与,||或 > 赋值运算符
(三)语句
1.赋值语句
#include<stdio.h>
int main()
{
int a, b;
a = 1; //将1赋给a
b = 2; //将2赋给b
printf("%d %d %d\n", a, b, a+b);
a += 2; //相当于 a = a + 2,将a+2赋给a
b *= 2; //相当于 b = b * 2, 将b*2赋给b
printf("%d %d %d\n", a, b, a+b);
char c1, c2;
c1 = 'a'; //将'a'赋给c1
c2 = c1 + 1; //将c1 + 1赋给c2, c1 + 1 表示c1的ASCII码+1
printf("%c %d\n", c1, c1);
printf("%c %d\n", c2, c2);
return 0;
}
2.输入输出语句
(1)输入输出函数scanf()和printf()
#include<stdio.h>
int main()
{
int a;
scanf("%d", &a); //输入十进制基本整型
printf("%d %o %x\n", a, a, a); //输出十进制,八进制和十六进制基本整型
short b;
scanf("%hd", &b); //输入十进制短整型
printf("%hd %ho %hx\n", b, b, b); //输出十进制,八进制和十六进制短整型
long c;
scanf("%ld", &c); //输入的十进制长整型
printf("%ld %lo %lx\n", c, c, c); //输出十进制,八进制和十六进制长整型
float d;
scanf("%f", &d); //输入单精度浮点型
printf("%f\n%6.2f\n%-6.2f\n", d, d, d); //按默认格式输出,在六个数位右对齐保留两位小数输出,在六个数位左对齐保留两位小数输出
double e;
scanf("%lf", &e); //输入双精度浮点型
printf("%lf\n%6.2lf\n%-6.2lf\n", e, e, e); //按默认格式输出,在六个数位右对齐保留两位小数输出,在六个数位左对齐保留两位小数输出
return 0;
}
#include<stdio.h>
int main()
{
char c1;
scanf("%c", &c1); //通过输入字符输入字符型
printf("%c\n", c1); //输出字符型
char c2;
scanf("%d", &c2); //通过输入ASCII码输入字符型
printf("%c\n", c2); //输出字符型
char c3[10];
scanf("%s", &c3); //输入指定长度的字符串
printf("%s", c3); //输出字符串
return 0;
}
(2)字符输入输出函数getchar()和putchar()
#include<stdio.h>
int main()
{
char c1, c2;
c1 = getchar(); //若输入c1的字符后按enter,会把enter即'\r'赋给c2
c2 = getchar();
putchar(c1);
putchar(c2);
putchar('\n');
return 0;
}
3.if语句
//给学生的成绩评定等级,90~100为A,80~89为B,70~79为C, 60~69为D, 0~59为E
#include<stdio.h>
int main()
{
float score;
char grade;
printf("please input the score of the student:\n");
scanf("%f", &score);
if (score>=90 && score <=100)
{
grade = 'A';
}
else if (score>=80 && score <=89)
{
grade = 'B';
}
else if (score>=70 && score <=79)
{
grade = 'C';
}
else if (score>=60 && score <=69)
{
grade = 'D';
}
else if (score>=0 && score <=59)
{
grade = 'E';
}
else //即分数>100或<0的情况
{
printf("the score you input is error.\n");
}
printf("%c\n", grade);
return 0;
}
4.switch语句
//给学生的成绩等级反馈成绩区间,90~100为A,80~89为B,70~79为C, 60~69为D, 0~59为E
#include<stdio.h>
int main()
{
char grade;
printf("please input the grade of the student:\n");
scanf("%c", &grade);
switch(grade) //将switch得到的grade的值与各case中的值匹配
{
case 'A': printf("90~100\n"); break; //case后的值为常量
case 'B': printf("80~89\n"); break;
case 'C': printf("70~79\n"); break;
case 'D': printf("60~69\n"); break;
case 'E': printf("0~60\n"); break;
default: printf("the grade you input is wrong.\n");
}
return 0;
}
5.while语句
//计算从1加到100的和
#include<stdio.h>
int main()
{
int i = 1, sum = 0;
while (i <= 100) //先判断后执行,若while的条件为假,循环体执行0次
{
sum += i;
i++;
}
printf("%d\n", sum);
return 0;
}
6.do···while语句
//计算从1加到100的和
#include<stdio.h>
int main()
{
int i = 1, sum = 0;
do
{
sum += i;
i++;
} while (i <= 100); //先执行后判断,若while的条件为假,循环体执行1次
printf("%d\n", sum);
return 0;
}
7.for语句
//计算从1加到100的和
#include<stdio.h>
int main()
{
int i , sum = 0;
for (i = 1; i <= 100; i++) //for(循环变量赋初值;循环条件;循环变量增值)
{
sum += i;
}
printf("%d\n", sum);
return 0;
}
8.break语句和continue语句
//输出一个4*5的矩阵
#include<stdio.h>
int main()
{
int i , j, n = 0;
for (i = 1; i <= 4; i++) //行
{
for (j = 1; j <= 5; j++, n++) //列
{
if (n % 5 == 0)
{
printf ("\n"); //换行
}
printf("%d\t", i * j);
}
}
return 0;
}
(1)break语句提前终止整个循环
//输出一个4*5的矩阵
#include<stdio.h>
int main()
{
int i , j, n = 0;
for (i = 1; i <= 4; i++) //行
{
for (j = 1; j <= 5; j++, n++) //列
{
if (n % 5 == 0)
{
printf ("\n"); //换行
}
if (i == 3 && j == 1)
{
break; //终止整个内循环,不输出第3行
}
printf("%d\t", i * j);
}
}
return 0;
}
(2)continue语句提前结束本次循环
//输出一个4*5的矩阵
#include<stdio.h>
int main()
{
int i , j, n = 0;
for (i = 1; i <= 4; i++) //行
{
for (j = 1; j <= 5; j++, n++) //列
{
if (n % 5 == 0)
{
printf ("\n"); //换行
}
if (i == 3 && j == 1)
{
continue; //提前结束内循环,不输出原本第3行第1列的元素
}
printf("%d\t", i * j);
}
}
return 0;
}
(四)数组
1.一维数组
//冒泡排序
#include<stdio.h>
int main()
{
int a[10];
int i, j, temp;
printf("please input 10 numbers:\n");
for (i = 0; i < 10; i++)
{
scanf("%d", &a[i]);
}
for (j = 0; j < 9; j++) //共9趟比较
{
for (i = 0; i < 9 - i; i++) //每趟比较9-i次
{
if (a[i] > a[i + 1])
{
temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
}
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 i, j, temp;
printf("please input 10 numbers:\n");
for (i = 0; i < 10; i++)
{
scanf("%d", &a[i]);
}
for (j = 0; j < 9; j++)
{
for (i = j + 1; i < 10 ; i++) //将这个数之后的数与这个数比较
{
if (a[j] > a[i])
{
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
printf("the sorted numbers:\n");
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
2.二维数组
//矩阵转置
#include<stdio.h>
int main()
{
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int b[3][2], i, j;
printf("array a:\n");
for (i = 0; i < 2; i++) //处理行
{
for (j = 0; j < 3; j++) //处理列
{
printf("%5d", a[i][j]);
b[j][i] = a[i][j];
}
printf("\n");
}
printf("array b:\n");
for (i = 0; i < 3; i++) //处理行
{
for (j = 0; j < 2; j++) //处理列
{
printf("%5d", b[i][j]);
}
printf("\n");
}
return 0;
}
3.字符串数组
#include<stdio.h>
int main()
{
int i, j;
char c1[10] = {'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'}; //定义并初始化
for (i = 0; i < 10; i++) //输出
{
printf("%c", c1[i]);
}
printf("\n");
char c2[3][3] = {{' ', '*', ' '}, {'*', '*', '*'}, {' ', '*', ' '}}; //定义并初始化
for (i = 0; i < 3; i++) //输出
{
for (j = 0; j < 3; j++)
{
printf("%c", c2[i][j]);
}
printf("\n");
}
return 0;
}
#include<stdio.h>
#include<string.h> //字符串函数头文件
int main()
{
char str[10];
gets(str); //输入在指定长度内的字符串
puts(str); //输出字符串
char str1[10] = {"hello"};
char str2[10] = {"world"};
printf("%s\n", strcat(str1, str2)); //字符串1,2拼接
printf("%s\n", strcpy(str1, str2)); //将字符串2复制到1中
char str3[10] = {"apple"};
char str4[10] = {"banana"};
if (strcmp(str3, str4) > 0) //将字符串3与字符串4比较,大于为正数,小于为负数,等于为0
{
printf(">\n");
}
if (strcmp(str3, str4) < 0)
{
printf("<\n");
}
if (strcmp(str3, str4) == 0)
{
printf("=\n");
}
printf("%d\n", strlen("helloworld")); //求字符串长度
return 0;
}
(五)函数
1.函数的定义、声明与调用,函数的形参和实参
#include<stdio.h>
int main()
{
int max(int x, int y); //函数声明
int a, b, c;
printf("please innput 2 numbers:\n");
scanf("%d%d", &a, &b);
c = max(a, b); //函数调用,a,b为实参
printf("max is: %d\n", c);
return 0;
}
int max(int x, int y) //函数定义,x,y为形参
{
int z;
z = x > y ? x : y;
return z;
}
2.函数的嵌套调用
在一个函数中调用另一个函数。
#include<stdio.h>
int main()
{
int max4(int a, int b, int c, int d);
int a, b, c, d, max;
printf("please innput 4 numbers:\n");
scanf("%d%d%d%d", &a, &b, &c, &d);
max = max4(a, b, c, d);
printf("max is: %d\n", max);
return 0;
}
int max2(int x, int y) //返回x,y的最大值
{
int z;
z = x > y ? x : y;
return z;
}
int max4(int a, int b, int c, int d)
{
int max2(int x, int y); //函数的嵌套调用
int m;
m = max2(a, b); //求a,b最大值
m = max2(m, c); //求a,b,c最大值
m = max2(m, d); //求a,b,c,d最大值
return m;
}
3.函数的递归调用
在函数内调用它本身。
//用递归法求n的阶乘
#include<stdio.h>
int main()
{
int fac(int n);
int n, res;
printf("please innput an integer number: ");
scanf("%d", &n);
res = fac(n);
printf("%d! = %d\n", n, res);
return 0;
}
int fac(int n)
{
int f;
if (n < 0)
{
printf("data error\n");
}
else if (n == 0 ||n == 1) //0和1的阶乘都为1
{
f =1;
}
else
{
f = fac(n -1) *n; //函数的递归调用
}
return f;
}
4.全局变量与局部变量
①全局变量在函数外部,通常用大写字母表示。
②全局变量可作用于全部函数,局部变量只能作用于其所在的函数。
③全局变量与局部变量同名时,以局部变量为准。
(六)指针
1.指针与指针变量
指针:地址
指针变量:存放地址的变量,其值为地址即指针
(&:取地址符; *:取值符)
//输入a,b两个整数,按先大后小的顺序输出a,b
#include<stdio.h>
int main()
{
int a, b, *p1, *p2, *p;
printf("please input 2 ingeter numbers: ");
scanf("%d%d", &a, &b);
p1 = &a; //p1指向a,即将a的地址赋给p1
p2 = &b; //p2指向b,即将b的地址赋给p2
if (a < b) //若a<b,交换p1,p2所储存的地址
{
p = p1;
p1 = p2;
p2 = p;
}
printf("max = %d, min = %d\n", *p1, *p2); //输出p1,p2所指变量的值,即通过p1,p2所储存的地址找相应的值
return 0;
}
2.指针变量作函数参数
//输入a,b两个整数,按先大后小的顺序输出a,b
#include<stdio.h>
int main()
{
void swap(int *p1, int *p2); //指针变量作形参
int a, b, *p1, *p2;
printf("please input 2 ingeter numbers: ");
scanf("%d%d", &a, &b);
p1 = &a;
p2 = &b;
if (a < b)
{
swap(p1, p2); //指针变量作实参
}
printf("max = %d, min = %d\n", *p1, *p2);
return 0;
}
void swap(int *p1, int *p2) //交换指针所指的值
{
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
3.通过指针引用数组
(1)通过指针引用一维数组
//将数组a的n个整数按相反顺序存放
#include<stdio.h>
int main()
{
void inv(int *a, int n);
int i, a[10] = {2, 1, 4, 3, 6, 5, 8, 7, 10, 9};
printf("the original array:\n");
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
inv(a, 10);
printf("the inverted array:\n");
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
void inv(int *a, int n)
{
int temp;
int *l, *r, *m;
l = a; //l指向数组首元素
r = a + n - 1; //r指向数组尾元素
m = a + (n - 1) / 2; //m指向数组中间元素
for (; l <= m; l++, r--)
{
temp = *l;
*l = * r;
*r = temp;
}
}
(2)通过指针引用多维数组
对于多维数组a
a[i] + j ,*(a + i)+j代表元素a[i][j]的地址
*(a[i] + j) ,*(*(a + i)+j)代表元素a[i][j]的值
4.通过指针引用字符串
//将字符串a的内容复制给b
#include<stdio.h>
int main()
{
char a[20] = "helloworld", b[20], *p1, *p2;
p1 = a; //p1,p2分别指向a数组和b数组的首元素
p2 = b;
for (; *p1 != '\0'; p1++, p2++)
{
*p2 = *p1; //将p1所指元素的值赋给p2
}
*p2 = '\0'; //把字符串a的内容全部复制到b后,在b的末尾加上'\0'
printf("string a is : %s\n", a);
printf("string b is : %s\n", b);
return 0;
}
(七)结构体
结构体:由不同类型数据组成的组合型的数据结构。
1.结构体变量
//输入两个学生的成绩并比较
#include <stdio.h>
struct Student //声明结构体类型struct Student
{
int num;
char name[20];
float score;
};
int main()
{
struct Student student1, student2; //定义结构体变量
scanf("%d%s%f", &student1.num, student1.name, &student1.score); //初始化结构体变量
scanf("%d%s%f", &student2.num, student2.name, &student2.score);
printf("The higher score is:\n");
if (student1.score > student2.score) //引用结构体变量
{
printf("%d %s %6.2f\n", student1.num, student1.name, student1.score);
}
else if (student1.score < student2.score)
{
printf("%d %s %6.2f\n", student2.num, student2.name, student2.score);
}
else
{
printf("%d %s %6.2f\n", student1.num, student1.name, student1.score);
printf("%d %s %6.2f\n", student2.num, student2.name, student2.score);
}
return 0;
}
2.结构体数组
//用结构体数组存放n个学生的信息并按成绩排序
#include <stdio.h>
struct Student //声明结构体类型struct Student
{
int num;
char name[20];
float score;
};
int main()
{
struct Student stu[4] = {{101, "zhao", 66}, {102, "qian", 88}, {103, "sun", 77}, {104, "li", 99}};
//定义并初始化结构体数组
struct Student temp;
//定义结构体变量用于交换
const int n = 4;
//定义常变量n,在程序运行时其值不变
int i, j;
for (i = 0; i < n - 1; ++i)
{
for (j = i + 1; j < n; ++j)
{
if (stu[j].score > stu[i].score)
{
temp = stu[i];
stu[i] = stu[j];
stu[j] = temp;
}
}
}
printf("The order is:\n");
for (i = 0; i < n; i++)
{
printf("%6d%8s%6.2f\n", stu[i].num, stu[i].name, stu[i].score);
}
return 0;
}
3.结构体指针
(1)指向结构体变量的指针
//通过指向结构体变量的指针访问结构体变量中的成员
#include <stdio.h>
struct Student //声明结构体类型struct Student
{
int num;
char name[20];
float score;
} student = {101, "zhao",88}; //定义并初始化结构体变量student
int main()
{
struct Student *p; //定义指向结构体变量的指针
p = &student;
printf("%6d%8s%6.2f\n", (*p).num, (*p).name, (*p).score); //通过指针访问结构体变量中的成员
return 0;
}
(2)指向结构体数组的指针
//通过指向结构体数组的指针输出存放有学生信息的结构体数组中学生的全部信息
#include <stdio.h>
struct Student //声明结构体类型struct Student
{
int num;
char name[20];
float score;
} stu[3] = {{101, "zhao", 88}, {102, "qian", 77}, {103, "sun", 99}}; //定义并初始化结构体数组stu
int main()
{
struct Student *p; //定义指向结构体数组的指针
for (p = stu; p < stu + 3; p++) //stu为stu数组中首元素的地址
{
printf("%6d%8s%6.2f\n", p->num, p->name, p->score); //通过指针输出结构体数组中元素的信息
}
}
(3)用结构体变量和结构体变量的指针作函数参数
//输入N个学生的成绩,输出成绩最高的学生的信息,分别用3个函数input,max,print来实现
#include <stdio.h>
#define N 3 //用符号常量定义N=5
struct Student
{
int num;
char name[20];
float score;
};
int main()
{
void input(struct Student stu[]);
struct Student max(struct Student stu[]);
void print(struct Student stud);
struct Student stu[N]; //定义结构体数组
struct Student *p = stu; //定义指向结构体数组的指针
input(p);
print(max(p)); //将max函数返回的结构体变量作为函数的实参
return 0;
}
void input(struct Student stu[]) //将结构体数组作为函数的形参
{
int i;
printf("Please input the number,name and score of the students:\n");
for (i = 0; i < N; ++i)
{
scanf("%d%s%f", &stu[i].num, stu[i].name, &stu[i].score);
}
}
struct Student max(struct Student stu[]) //将结构体数组作为函数的形参
{
int i, m = 0;
for (i = 0; i < N; ++i)
{
if (stu[i].score > stu[m].score)
{
m = i; //用m存放成绩最高的学生在数组中的序号
}
}
return stu[m]; //返回成绩最高学生的结构体变量
}
void print(struct Student stud) //将结构体变量作为函数形参
{
printf("The highest score student is:\n");
printf("%6d%8s%6.2f\n", stud.num, stud.name, stud.score);
}
4.用指针处理链表
链表:动态地进行存储分配的一种结构。
链表的头指针head存放一个地址,该地址指向一个元素,链表中的每个元素称为结点,每个结点包含两部分,数据和下一个结点的地址,head指向第一个元素,第一个元素指向第二个元素······直到最后一个元素,该元素不再指向其他元素,称表尾,其地址存放“NULL”(空地址),链表到此结束。
让p = head,不断执行语句p = p->next至p = NULL可将整个链表遍历。
(1)静态链表的建立和输出
//建立一个静态链表,由包含3个学生信息的结点组成,并输出各结点的数据
#include <stdio.h>
struct Student
{
int num;
float score;
struct Student *next;
};
int main()
{
struct Student a, b, c, *head, *p; //定义三个结构体变量a,b,c作为链表的结点
a.num = 101;
a.score = 88;
b.num = 102;
b.score = 77;
c.num = 103;
c.score = 99;
head = &a; //头指针head存放结点a的地址
a.next = &b; //结点a的next成员存放结点b的地址
b.next = &c; //结点b的next成员存放结点c的地址
c.next = NULL; //结点c的next成员不存放其他结点的地址
p = head; //p指向head结点,即指向a的地址
while (p != NULL) //当p存放空地址时循环结束
{
printf("%6d%6.2f\n", p->num, p->score);
p = p->next; //将p的next成员指向的地址赋值给p
}
return 0;
}
(2)动态链表的建立和输出
//建立一个能输入多个学生信息的动态链表(输入0.0结束),并将其输出
#include <stdio.h>
#include <malloc.h>
#define LEN sizeof(struct Student) //用LEN表示struct Student类型数据的长度
struct Student
{
int num;
float score;
struct Student *next;
};
int n; //用n统计链表结点数
struct Student *creat() //建立链表的函数,该函数返回头指针
{
struct Student *head;
struct Student *p1, *p2;
n = 0;
p1 = p2 = (struct Student *)malloc(LEN); //开辟第一个结点并使p1,p2指向它
scanf("%d%f", &p1->num, &p1->score); //在p1所指的第一个结点输入第一个学生的信息
head = NULL; //先使head的值为NULL,即head不指向任何结点
while (p1->num != 0) //当输入学生的学号为零时循环结束
{
n = n + 1; //所统计的链表结点数加一
if (n == 1) //当为第一个结点时
{
head = p1; //把p1的值赋给head,即使head也指向所开辟的第一个结点,使该结点成为链表中的第一个结点
}
else
{
p2->next = p1; //将p1的值赋给p2->next,由于p2指向上一个结点,执行该语句就将刚建立的结点连接到上一个结点后
}
p2 = p1; //使p2指向刚建立的结点
p1 = (struct Student *)malloc(LEN); //开辟新的结点并使p1指向它
scanf("%d%f", &p1->num, &p1->score); //在p1所指的新的结点输入下一个学生的信息
}
p2->next = NULL; //将NULL赋值给p2->next,建表过程结束,由于循环结束,即使p1指向了新开辟的结点,也无法在链入链表中
return (head);
}
void print(struct Student *head) //输出链表的函数
{
struct Student *p;
printf("These %d records are:\n", n);
p = head; //使p指向第一个结点
if (head != NULL) //若不是空表
{
while (p != NULL) //若p不是空地址
{
printf("%6d%6.2f\n", p->num, p->score);
p = p->next; //使p指向下一个结点
}
}
}
int main()
{
struct Student *head;
head = creat();
print(head);
return 0;
}