C语言快速入门
前言
== 用例题读懂C语言 ==
C语言是结构化的程序设计语言,共有三大结构,不同结构由不同语句构成
- 顺序结构
- 选择结构
- 循环结构
语句:由分号;隔开的就是一条语句
例如:printf(“我爱C语言”);或者 2+9;
一、选择结构
构成选择结构有两种语句:
- if 语句
- switch语句
(一)if语句介绍
if语句有三种语法结构
|~|第一种|~|
if(表达式)//表达式为真 则执行 执行语句 为假则跳出该括号中的语句
{
执行语句;
}
/eg1:判断是否成年
#include <stdio.h>
int main()
{
int age = 10;
if (age <= 18)
{
printf("未成年\n");
}
return 0;
}
*/因为10小于18,表达式成立,所以打印未成年
/eg2:判断是否成年
#include <stdio.h>
int main()
{
int age = 20;
if (age <= 18)
{
printf("未成年\n");
}
return 0;
}
*/因为20大于18,表达式不成立,所以调试台什么都不显示
|~|第二种|~|
if(表达式)
{
执行语句1;
}
else
{
执行语句2;
}
/eg:判断是否成年
#include <stdio.h>
int main()
{
int age = 20;
if (age <= 18)
{
printf("未成年\n");//语句1
}
else
{
printf("成年了\n");//语句2
}
return 0;
}
*/因为20大于18,表达式不成立,所以不执行if中语句,执行else否则中语句
*/如果满足age小于等于18,则执行语句1,否则执行语句2
|~|第三种|~|
if(表达式1)
{
执行语句1;
}else if(表达式1)
{
执行语句2;
}
else
{
执行语句3;
}
/eg:判断处于什么年龄段
#include <stdio.h>
int main()
{
int age = 23;
if (age <= 18)
{
printf("未成年\n");//语句1
}
else if (age <= 30)
{
printf("青年\n");//语句2
}
else
{
printf("壮年\n");//语句3
}
return 0;
}
*/如果满足age小于等于18,则执行语句1,否则判断age是否满足小于等于30,若满足则执行语句2,否则执行语句3
Tips:
*/else和离他最近的if语句匹配,故敲代码时注意加括号
*/ 注意格式
*/ if(5 == num) 变量常量比较时候 常量写左边 避免失误写成=时不好检查
(二)if语句例子
- 判断一个数是奇数还是偶数
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if (n % 2 == 0)//如果一个属余数等于0,则是偶数0%2=0;4%2=0 4除以2 余0
{
printf("%d是偶数", n);
}
else//否则的话 9除以2 余数是1 不满足if中的判断条件
{
printf("%d是奇数", n);
}
return 0;
}
- 输出1-100之间的奇数
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 100; i++)//for循环产生1-100数字
{
if (i % 2 == 1)//if判断 如果奇数打印出来
{
printf("%d\n", i);
}
}
return 0;
}
(三)switch语句介绍
swich语句常用于多分枝结构,比如输入1执行语句1,输入2执行语句2,输入3执行语句3…
tips:
*/只可以用数字和字符进行选择(入口只能是整数或者字符)
switch(整形表达式)
{
case 整形常量表达式1://case决定入口 break决定出口 没有break继续顺序执行
执行语句1;
break;
case 整形常量表达式2:
执行语句2;
break;
default://默认的
所有不满足整形常量表达式的,默认执行的语句;
break;
}
(四)switch语句例子
输入1 2 3 4分别对应输出星期一、星期二、星期三、星期四,输入其他输出别出BUG
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期一");
break;
case 2:
printf("星期二");
break;
case 3:
printf("星期三");
break;
case 4:
printf("星期四");
break;
default:
printf("别出BUG");
break;
}
return 0;
}
二、循环结构
构成循环结构有三种语句:
- while 循环语句
- for 循环语句
- do while 循环语句
(一)while语句介绍
|~|一|~|
while(表达式)//同if 表达式为真则执行 执行语句,为假则跳出括号
{
执行语句;
}
/eg:打印1-10
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)//打印数字 直到i不小于等于10
{
printf("%d\n", i);
i++;
}
return 0;
}
|~|二|~|:break 和 continue介绍
*/循环中break介绍:
直接跳出循环
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)//如果等于5 进入括号
{
break;//执行break跳出循环
}
printf("%d\n", i);
i++;
}
return 0;
}
*/循环中continue介绍:
continue是跳过本次循环中continue后面的代码,直接去判断部分,看是否进行下一次循环
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
{
continue;
}
printf("%d\n", i);
i++;
}
return 0;
}
*/结果是1234死循环
(二)while语句例子
前置知识:
//获取字符 和 打印字符
#include<stdio.h>
int main()
{
int ch = getchar();//getchar函数返回值是整形变量
//printf("%c", ch);
putchar(ch);
return 0;
}
- 反复从键盘上读取字符 并打印出来:
#include<stdio.h>
int main()
{
int ch = 0;
//键盘按 ctrl + z 等于getchar了EOF
while (ch = getchar() != EOF)//EOF 等于-1 文件结束标志
{
putchar(ch);
}
return 0;
}
//或者写成如下
#include<stdio.h>
int main()
{
int ch = 0;
//键盘按 ctrl + z 等于getchar了EOF
while ( ch != EOF)//EOF 等于-1 文件结束标志
{
ch = getchar();//getchar 先读取A然后打印A 然后读取回车 然后打印\n表现的就是 输入A 换行打印A
putchar(ch);
}
return 0;
}
- 输入密码,并确认密码,确认 输出正确 否则错误
|~|情况一|~|
#include<stdio.h>
int main()
{
char pass[20] = {
0 };
int ch = 0;
printf("请输入密码>");
scanf("%s", pass);
printf("请确认密码Y/N>");
ch = getchar(ch);
if (ch == 'Y')
{
printf("密码正确");
}
else
{
printf("密码错误");
}
return 0;
}
*/getchar 和 printf 从输入缓冲区读取数据
*/键盘输入数据到输入缓冲区
键盘输入123456 并敲回车 会触发scanf操作 将数据送到输入缓冲区
但scanf只会将123456存储到pass中 也就是空格前的数据拿走存储到pass 此时缓冲区中剩下一个回车(\n),
getchar 没有等待 直接将\放入 了ch中
|~|情况二|~|
怎么解决呢,只需要将那个\n读取出来就行
#include<stdio.h>
int main()
{
char pass[20] = {
0 };
int ch = 0;
printf("请输入密码>");
scanf("%s", pass);
printf("请确认密码Y/N>");
getchar(); //读取空格
ch = getchar(ch);
if (ch == 'Y')
{
printf("密码正确");
}
else
{
printf("密码错误");
}
return 0;
}
|~|情况三|~|
如果我输入的是123456 abcd呢 scanf将第一个空格前的123456读取完了,那么剩下的abcd和空格 也得清空
#include<stdio.h>
int main()
{
char pass[20] = {
0 };
int ch = 0;
printf("请输入密码>");
scanf("%s", pass);
printf("请确认密码Y/N>");
/* 清零缓存区中的多个字符*/
int tmp = 0;
while ((tmp = getchar()) != '\n')//如果得到空格就一直循环 直到得到空格 空格不等于空格条件为假 跳出循环
{
;
}
ch = getchar(ch);
if (ch == 'Y')
{
printf("密码正确");
}
else
{
printf("密码错误");
}
return 0;
}
- 输入一个数字字符 并且打印,输入其他字符不打印
#include<stdio.h>
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF )//一直循环输入打印 直到给了结束条件EOF
{
if (ch < '0' || ch>'9')
{
continue;
}
putchar(ch);
}
return 0;
}
(三)for循环语句介绍
|~|一|~|
for(表达式1;表达式2;表达式3)//(初始化部分;判断部分;调整部分)
{
执行语句;
}
/eg:打印1-10
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)//初始化;判断条件;调整 初始化只执行1次
{
printf("%d ", i);
}
return 0;
}
|~|二|~|:break 和 continue介绍
*/循环中break介绍:
直接跳出循环
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)//初始化;判断条件;调整
{
if (i == 5)
{
break;
}
printf("%d ", i);
}
return 0;
}
*/循环中continue介绍:
continue是跳过本次循环中continue后面的代码,直接去判断部分,看是否进行下一次循环
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)//初始化;判断条件;调整
{
if (i == 5)
{
continue;//5的时候不打印 直接跳到for中 i++
}
printf("%d ", i);
}
return 0;
}
Tips:
不要在for循环内 修改循环变量 防止for循环失去控制
2.建议for语句的循环控制变量的取值采用“前闭后开区间"写法 i<10而不是i<=9
(四)for循环语句例子
- 省略循环变量情况
*/只输出了3个gaga 因为在执行一遍j循环后 j没有被初始化为1 故不建议这么写
#include<stdio.h>
int main()
{
int i = 0;
int j = 0;
for (; i < 3; i++)
{
for (; j < 3; j++)
{
printf("gaga ");
}
}
return 0;
}
- for循环嵌套输出9次gaga
#include<stdio.h>
int main()
{
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0;j < 3; j++)
{
printf("gaga ");
}
}
return 0;
}
(五)do while循环语句介绍
特点:循环体必定执行一次,不太常用
|~|一|~|
do
循环语句;
while(表达式);
/eg:打印1-10
#include<stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
|~|二|~|:break 和 continue介绍
*/循环中break介绍:
直接跳出循环
#include<stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
{
break;
}
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}}
*/循环中continue介绍:
continue是跳过本次循环中continue后面的代码,直接去判断部分,看是否进行下一次循环
#include<stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
{
continue;
}
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
(六)三大循环练习题
- 计算n的阶乘
#include<stdio.h>
int main()
{
int i = 0;
int n = 0;
int ret = 1;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
ret = ret * i;
}
printf("%d", ret);
return 0;
}
- 计算n的阶乘
#include<stdio.h>
int main()
{
int i = 0;
int n = 0;
int ret = 1;
int sum = 0;
//scanf("%d", &n);
for (n = 1; n <= 10; n++)
{
ret = 1;//每一次进入阶乘循环都初始化阶乘结果为1
for (i = 1; i <= n; i++)
{
ret = ret * i;
}
sum = sum + ret;
}
printf("%d", sum);
return 0;
}
优化:
#include<stdio.h>
int main()
{
int n = 0;
int ret = 1;
int sum = 0;
for (n = 1; n <= 3; n++)
{
ret = ret * n;//4!等于4*3! ret存储的是上一个数的阶乘 上一个数阶乘×本次数字
sum = sum + ret; //在将每次的结果加和
}
printf("%d", sum);
return 0;
}
- 在一个有序数组中查找具体的某个数字n
#include<stdio.h>
int main()
{
int arr[10] = {
1,2,3,4,5,6,7,8,9,10};
int k = 2;
int sz = ((sizeof(arr)) / sizeof(arr[0]));//数组的元素个数
int right = sz-1;//数组元素个数减一是其右下标
int left = 0;//左下标
while(left <= right)//while内代码是一次二分查找的所有可能性 需要进行多次二分查找
{
int cim = (right + left) / 2;//最开始是4
if (arr[cim] < k) //下标对应的是中间数字 如果中间数字小于k 到么找中间数字右边的就行
{
left = cim + 1;//那就挪动左边的下标指示 然后跳出循环 回到循环表达式判断是否进入循环
}
else if (arr[cim] > k)//左指示为5 右指示为9 相加/2 等于7 下标7对应数字8 8大于k到这部 也就是只需要判断 数字8左边的数字
{
right = cim - 1;//挪动右边的下标指示 到数字8的左边 作为新的下标指示 跳出 循环回到循环表达式判断
}
else
{
printf("找到了:下标是%d", cim);
break;//找到咯 跳出循环咯 如果不加 会一直打印
}
}
if (right <left)
{
printf("找不到了");
}
return 0;
}
- 从两边往中间打印字符
#include<stdio.h>
#include<windows.h>
int main()
{
char arr1[] = "I Love LiuYang";
char arr2[] = "##############";
int left = 0;
int right = strlen(arr2)-1;//计算字符串数组长度 -1后是最右边数组下标
//int sz = ((sizeof(arr1)) / sizeof(arr1[0]));//数组的元素个数 包括了结束标志/0 但是strlen算的只是数组长度
while (left <= right)//数组下标不能交叉
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n", arr2);//打印字符串
Sleep(500);//1000延时1s
system("cls");//打印清屏
left++;
right--;
}
printf("%s\n", arr2);//打印最后一次字符
return 0;
}
- 用户登录场景
#include<stdio.h>
#include<string.h>
int main()
{
char password[20] = {
0 };
int i = 0;
for (i = 0; i < 3; i++)
{
printf("请输入密码:(三次错误将退出程序)\n");
scanf("%s", password);//数组名 不用取地址
//if (password == "123456")//但是 字符串比较不能这么比较
if (strcmp(password, "123456") == 0)//返回0 表示相等//从左到右依次比较对应位置的ASCLL码值 当对应位置不相同时 ASCLL大的 值就大
{
printf("密码正确\n");
break;
}
else if(i<=1)
{
printf("密码错误%d次请重新输入:\n",i+1);//如果第三次也错 不打印这句
}
else
{
printf("三次错误 退出程序");
}
}
//if (i == 3)
//{
// printf("三次错误 退出程序");
//}
}
- 猜数字游戏
1.自动产生一个1-100之间的随机数
2.猜数字
------a.猜对了,就恭喜你,游戏结束
------b.你猜错了,会告诉猜大了,还是猜小了,继续猜,直到猜对
3.游戏一个一直玩,除非退出游戏
/*
思路:
上来玩游戏 用dowhile
先打印个菜单
打印完 switch选择菜单
然后封装游戏函数:1.生成随机数 2. 设置随机数初始值3. while死循环 猜对跳出 反馈大小结果
*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()
{
printf("******欢迎来到猜数字小游戏*******\n");
printf("*********************************\n");
printf("********1.开始游戏***************\n");
printf("********0.退出游戏***************\n");
printf("*********************************\n");
}
void game()
{
int suiji = rand();//产生随机数 但每次都一样 返回了0-32767的数字//调用rand前设置srand设置随机数起点
int red = suiji % 100 + 1; //%100的值是0 -99 加1后变成1到100
int guess = 0;
while (1)
{
printf("请猜数字\n");
scanf("%d", &guess);
if (guess < red)
{
printf("猜小了\n");
}
else if (guess > red)
{
printf("猜大了\n");
}
else
{
printf("猜对了,随机数是%d\n",red);
break;
}
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));//括号中给随机变量 就可以生成随机数 填时间戳
do
{
menu();
printf("请选择>\n");
scanf("%d",&input);
switch (input)
{
case 1:
game();//
break;//游戏结束 跳出switch 判断 是否满足循环表达式 因为input一直是1 所以 执行菜单
case 0:
printf("退出游戏\n");
break;
default:
printf("重新选择\n");
break;
}
} while (input);//0退出
return 0;
}