一 C语言的流程控制
1 分支语句
分支语句可以根据情况从多组语句中选择一组执行
a if…else语句
if(逻辑表达式1){ //有且只有一个
语句组1
}
else if(逻辑表达式2){ //可以没有,也可以有多个
语句组2
}
else{ //最多一个,可能没有
语句组3
}
b switch … case语句也是一种分支语句
2 循环语句
循环语句可以用来反复执行类似的操作
a for语句
for语句是一种循环语句,其格式如下:
int loop=0;
(loop=开始数字;loop和循环变量的关系;loop变化规律){
一次处理的代码
}
假设有如下循环语句
for(1;2;3){
4
}
执行顺序如下
[1,2] [4,3,2] [4,3,2] ……
编号为2的语句是逻辑表达式,如果为真则启动下一组,编号为4的语句有可能根本就不执行
循环中可以使用break语句随时终止循环的执行
循环中使用continue语句可以把一部分语句跳过,直接到大括号末尾
循环嵌套可以处理复杂的循环问题
外层循环的循环变量表示每个组代表数字的变化过程,内层循环的循环变量表示组内某个数字的变化过程,内循环的开始数字和结束数字可能都需要通过外循环的循环变量计算得到
for循环的多种写法:
1、单条循环语句可以省略大括号
2、使用逗号操作符
3、在循环中声明循环变量,c99规范中才支持,并且声明的变量只在该循环中有效
4、可以小括号中只保留循环条件
5、还可以空语句
6、死循环 for(;;) printf(“*”);
b while语句
while语句也是一种循环语句,格式如下
while(1){
2
}
[1] [2,1] [2,1] ……[2,1]
c do … while()语句
do…while语句也是一种循环语句
do{
重复执行的语句
}while(逻辑表达式)
执行顺序是【2,1】【2,1】…【2,1】
可以保证大括号内的语句至少执行一遍
while语句也可以写空语句和死循环
d goto语句可以任意跳转到任何一条语句
二 数组
1 数组理论基础
- 数组用来把多个同类型的变量合并成一个整体,一个数组只有一个名字
- 数组中每个变量都有一个下标,通过下标区分不同的变量
下标的范围是从0开始到个数减一为止,超过范围的下标不可以使用 数组中的变量是前后排列的,之间没有空隙,在循环中操作数组可以最大的发挥数组的优势
数组可以在声明的时候初始化,初始化的时候没有提供初始化数据的变量会被自动初始化为0。
- 数组名在计算机里被当成数字使用,它就是数组中第一个变量的地址,因此,数组名称不可以被赋值。数组名称加常数可以得到常数做下标的变量的地址 arr+2和&arr[2]结果一样,都是第三个元素的地址
- *(arr+3)可以用来表示下标为3的变量的值
- 对数组名称使用sizeof关键字可以得到整个数组的大小
- c99规范中支持变长数组,就是数组长度可以用一个变量表示,但是变长数组不可以被初始化
arr.c
#include <stdio.h>
int main() {
int arr[5] = {}, size = 0;
printf("arr是%p\n", arr);
//arr = 0; 不可以被赋值
printf("arr + 2是%p,&arr[2]是%p\n", arr + 2, &arr[2]);
*(arr + 3) = 3;
printf("arr[3]是%d\n", arr[3]);
printf("sizeof(arr)是%d\n", sizeof(arr));
printf("变量个数是%d\n", sizeof(arr) / sizeof(arr[0]));
printf("请输入一个数字:");
scanf("%d", &size);
//int val[size] = {}; 变长数组不可以被初始化
return 0;
}
2 二维数组
二维数组由多个一维数组构成
二维数组中每个一维数组也有一个编号(下标),下标的范围是从0开始到一维数组个数减一为止,二维数组在使用的时候需要提供一个一维数组的下标和一维数组内部某个变量的下标。
二维数组可以采用类似一维数组初始化的方法进行初始化,如果初始化的时候提供足够多的初始化数据则可以不声明一维数组的个数。
二维数组在使用时可以只提供一个下标,这个下标作为组下标。
#include <stdio.h>
int main() {
//int arr[2][3] = {{1, 2},{4, 5, 6}};
//int arr[2][3] = {1, 2, 4, 5, 6};
//int arr[][3] = {{1, 2}, {4, 5, 6}};
int arr[][3] = {1, 2, 4, 5, 6};
int row = 0, col = 0;
for (row = 0;row <= 1;row++) {
for (col = 0;col <= 2;col++) {
printf("%d ", arr[row][col]);
}
printf("\n");
}
return 0;
}
二维数组名称和其中第一个一维数组名称代表的地址数据一样 arr arr[0],但他们的级别不同,所以不能混用 arr+1 arr[0]+1
对二维数组名称也可以进行sizeof计算,结果是整个二维数组中所有变量的大小总和。
#include <stdio.h>
int main() {
int arr[3][4] = {};
printf("arr[1]是%p,arr[2]是%p\n", arr[1], arr[2]);
printf("arr是%p,arr[0]是%p\n", arr, arr[0]);
printf("arr + 1是%p,arr[0] + 1是%p\n", arr + 1, arr[0] + 1);
printf("sizeof(arr)是%d\n", sizeof(arr));
return 0;
}
/*
彩票作业
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int lottery[] = {0, 0, 0, 0, 0, 0, 0};
int num = 0, val = 0, pos = 0;
srand(time(0));
//每次循环生成一个新数字
while (num < 7) {
val = rand() % 36 + 1;
//用新数字和每个旧数字比较
for (pos = 0;pos <= num - 1;pos++) {
if (val == lottery[pos]) {
break;
}
}
//如果新数字和所有旧数字都不一样
if (!(pos <= num - 1)) {
lottery[num] = val;
num++;
}
}
//显示数组中的每个数字
for (pos = 0;pos <= 6;pos++) {
printf("%d ", lottery[pos]);
}
printf("\n");
return 0;
}
/*
身份证作业
*/
#include <stdio.h>
int main() {
int arr[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
int arr1[] = {1, 0, -1, 9, 8, 7, 6, 5, 4, 3, 2};
int arr2[18], pos = 0, sum = 0;
//获得身份证的18个数字
for (pos = 0;pos <= 17;pos++) {
printf("请输入第%d个数字:", pos + 1);
scanf("%d", &arr2[pos]);
}
//对身份证中前17个数字分别乘以对应的数字并把结果求和
for (pos = 0;pos <= 16;pos++) {
sum += arr[pos] * arr2[pos];
}
//验证校验码
printf("正确的校验码是%d\n", arr1[sum % 11]);
if (arr1[sum % 11] == arr2[17]) {
printf("验证成功\n");
}
else {
printf("验证失败\n");
}
return 0;
}
/*
圈叉棋练习
*/
#include <stdio.h>
#include <stdbool.h>
void show(int map[][3], int);
int get_num(void);
void get_pos(int map[][3], int pos[]);
bool win(int map[][3], int, int, int, int, int, int);
void show(int map[][3], int size) {
int row = 0, col = 0;
for (row = 0;row <= size - 1;row++) {
for (col = 0;col <= 2;col++) {
if (!map[row][col]) {
printf(".");
}
else if (map[row][col] == 1) {
printf("O");
}
else {
printf("X");
}
}
printf("\n");
}
}
int get_num(void) {
int num = 0;
do {
printf("请输入编号(1到3之间):");
scanf("%d", &num);
} while (num < 1 || num > 3);
return num;
}
void get_pos(int map[][3], int pos[]) {
do {
pos[0] = get_num();
pos[1] = get_num();
} while (map[pos[0] - 1][pos[1] - 1]);
}
bool win(int map[][3], int row1, int col1, int row2, int col2, int row3, int col3) {
if (map[row1][col1] &&
map[row1][col1] == map[row2][col2] &&
map[row2][col2] == map[row3][col3]) {
printf("%c赢了\n", map[row1][col1] == 1? 'O' : 'X');
return true;
}
else {
return false;
}
}
int main() {
int map[3][3] = {}, pos[2] = {}, loop = 0;
show(map, 3);
for (loop = 0;loop <= 8;loop++) {
get_pos(map, pos);
map[pos[0] - 1][pos[1] - 1] = loop % 2 ? 2 : 1;
show(map, 3);
if (win(map, 0, 0, 0, 1, 0, 2)) {
break;
}
if (win(map, 1, 0, 1, 1, 1, 2)) {
break;
}
if (win(map, 2, 0, 2, 1, 2, 2)) {
break;
}
if (win(map, 0, 0, 1, 0, 2, 0)) {
break;
}
if (win(map, 0, 1, 1, 1, 2, 1)) {
break;
}
if (win(map, 0, 2, 1, 2, 2, 2)) {
break;
}
if (win(map, 0, 0, 1, 1, 2, 2)) {
break;
}
if (win(map, 0, 2, 1, 1, 2, 0)) {
break;
}
}
return 0;
}