C 语言基础
C 语言
1. 入门
优点:
-
功能强大
操作系统、嵌入式、动态库、服务器、应用程序、外挂、其他语言等 -
执行效率高
C语言描述问题比汇编语言简练,而代码质量与汇编语言相当 -
可移植性好
一个环境上用C语言编写的程序,不改动或稍加改动,就可移植到另一个完全不同的环境中运行 -
缺点:
面向过程的封装性不好与C++相比
语法限制不太严格,过于自由
2. 编写代码
编写代码的环境建议使用CLion
搭建过程不在演示。
2.1 基本
#include<stdio.h> // #include的意思是头文件包含,#include <stdio.h>代表包含stdio.h这个头文件
#include<stdlib.h>
// 所有的#开头的行,都代表预编译指令,预编译指令行结尾是没有分号的
int main() {
// 所有的可执行语句必须是在代码块里面
printf("Hello world\n");
system("pause");
return 0;
}
2.2 注释
两种格式
- 单行注释:
// 描述信息
通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明
- 多行注释:
/* 描述信息 */
通常放在一段代码的上方,对该段代码做整体说明提示:编译器在编译代码时,会忽略注释的内容
3. 数据类型与变量
3.1 关键字
作用:关键字是C中预先保留的单词(标识符)
- 在定义变量或者常量时候,不要用关键字
C关键字如下:
[auto] | [break] | [case] | [char] | [const] | [continue] | [default] | [do] |
---|---|---|---|---|---|---|---|
[double] | [else] | [enum] | [extern] | [float] | [for] | [goto] | [if] |
[int] | [long] | [register] | [return] | [short] | [signed] | [sizeof] | [static] |
[struct] | [switch] | [typedef] | [union] | [unsigned] | [void] | [volatile] | [while] |
提示:在给变量或者常量起名称时候,不要用C得关键字,否则会产生歧义。
3.2 变量
作用:给一段指定的内存空间起名,方便操作这段内存
语法:数据类型 变量名 = 初始值;
规定:变量名必须是字母、下划线、数字组成,且不能以数字开头。
示例:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
void test01()
{
//变量
//给内存空间起名 方便我们去操作这块内存
//变量 在程序运行期间 是可以改变的
int a = 10;
printf("a = %d\n", a);
a = 20;
printf("a = %d\n", a);
}
void test02()
{
//变量的定义 定义的同时给变量一个初始值
int a = 100;
printf("a = %d\n", a);
int b = 0; //定义一个变量,未初始化,结果未知
//int b; //error 没有初始化 ,vs不可以运行 gcc可以结果未知
printf("b = %d\n", b);
//建议在定义变量的同时 给变量一个初始值 默认给0
}
void test03()
{
//变量的声明
//如果变量的定义在变量使用的前面,属于自动声明
//如果变量的定义在变量使用的后面,需要显示声明,加入一个关键字 extern
extern int g_c;//告诉编译器 有个g_c的变量存在,在后面可以找到,如果提前使用了,先不要报错
printf("g_c = %d\n", g_c);
}
int g_c = 1000;
int main() {
test01();
system("pause");
return EXIT_SUCCESS;
}
注意:C++在创建变量时,必须给变量一个初始值,否则会报错
3.3 标识符命名规则
作用:C / C++
规定给标识符(变量、常量)命名时,有一套自己的规则
- 标识符不能是关键字
- 标识符只能由字母、数字、下划线组成
- 第一个字符必须为字母或下划线
- 标识符中字母区分大小写
建议:给标识符命名时,争取做到见名知意的效果,方便自己和他人的阅读
C语言变量命名规范主要遵循以下几个原则:
-
直观且可拼读:变量名应直观且易于拼读,能够直接反映变量的用途或含义,便于记忆和理解。
-
命名长度适中:命名应符合
min-length && max-information
原则,保持简洁,避免过长的命名。 -
大小写敏感:C语言中的标识符是区分大小写的,因此变量名的大小写应遵循一定的规则,以便于阅读和维护。
-
避免使用数字开头:变量名的开头不能是数字,应由字母或下划线开头。
-
避免使用空格、标点符号和类型说明符:变量名中不应包含空格、标点符号和类型说明符,如%、&、!、#、@、$等。
-
使用下划线命名法和小驼峰命名法:例如,使用
student_age
或studentAge
作为变量名。 -
常量使用大写命名:常量的命名应全部大写,例如
PI_VALUE
。 -
指针和宏的命名:指针变量名可以加上前缀表示,如
int *pStudentAge;
,宏定义应使用全大写,如#define MAX_STUDENTS 100
。 -
避免使用关键字:变量名不应与C语言的关键字相同,如
int case = 12;
是错误的,因为case
是C语言的关键字。 -
全局变量和函数的命名:全局变量或函数应加上范围限定符(如模块名缩写)以避免命名冲突,例如
g_pFileLog
表示全局变量。 -
缩写和一致性:如果使用缩写,应在整个系统中保持一致,并注明其意思。
遵循这些规范可以使代码更易于阅读和维护,提高代码的可读性和可维护性。
3.4 常量
作用:用于记录程序中不可更改的数据
C语言中的常量大概有以下五种表现形式
-
数值常量(整数型常量(整数) 、实数型常量(小数))
-
字符常量 'a' 'b' 'c' '\n' '\t'
-
字符串常量 "hello world"
-
#define 宏常量:
#define 常量名 常量值
-
通常在文件上方定义,表示一个常量
-
在程序中使用的时候会进行文本替换,因此最好不要在宏中定义表达式。
-
-
const修饰的变量
const 数据类型 常量名 = 常量值
- 通常在变量定义前加关键字
const
,修饰该变量为常量,不可修改.
- 通常在变量定义前加关键字
示例:
#define DAY 7
//常量 在程序运行期间 不可以改变的量
void test01()
{
//一共有5种表现的形式
//1、数值常量(整数型常量(整数) 、实数型常量(小数))
// 100 200 300 3.14 1.1 2.2 3.3
//100 = 200; //error 常量是不可以修改的!
//2、字符常量 'a' 'b' 'c' '\n' '\t'
//'a' = 'b'; error
//3、字符串常量 "hello world"
//"hello world" = "aaaa"; error
//4、符号常量 (宏常量)
//利用 #define
printf("一周一共有%d天\n", DAY);
//DAY = 14; error
//5、const 修饰的变量
const int month = 12;
printf("一年一共有%d月\n", month);
//month = 24; error 此时是一个常量了 不可以修改
}
3.5 整型
C 语言规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存。
作用:整型变量表示的是整数类型的数据
C 语言中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同:
数据类型 | 占用空间 | 取值范围 |
---|---|---|
short(短整型) | 2字节 | (-2^15 ~ 2^15-1) |
int(整型) | 4字节 | (-2^31 ~ 2^31-1) |
long(长整形) | Windows为4字节,Linux为4字节(32位),8字节(64位) | (-2^31 ~ 2^31-1) |
long long(长长整形) | 8字节 | (-2^63 ~ 2^63-1) |
通常情况下,在学习阶段我们使用的都是int
;
#include<stdio.h>
#include<stdlib.h>
void test01() {
// 超出范围;
short num1 = 32768; // - 32768 ~ 32767
// 正常赋值;
int num2 = 32768; // 9 位数 到 10 位数之间
long num3 = 10;
long long num4 = 10;
printf("num1 = %hd\n", num1);
printf("num2 = %d\n", num2);
printf("num3 = %ld\n", num3);
printf("num4 = %lld\n", num4);
}
int main() {
printf("Hello world\n");
test01();
// system("pause");
return 0;
}
3.6 字符型
作用:字符型变量用于显示单个字符
语法:char ch = 'a';
注意1:在显示字符型变量时,用单引号将字符括起来,不要用双引号
注意2:单引号内只能有一个字符,不可以是字符串
- C语言中字符型变量只占用
1个字节
。 - 字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元
// 提示 ASCII 码 表中 A=65, a=97
void test_char(){
char a = 'A';
printf("a=%c\n", a);
printf("a=%d\n", a); // 打印出 ASCII
printf("a=%d\n", a+32);
printf("a=%c\n", a+32); // +32 , 对应 A 的 ASCII, 打印出 ASCII
}
int main() {
printf("Hello world\n");
test_char();
// system("pause");
return 0;
}
3.7 字符串
字符串型常量是由一对双引号括起来的字符序列。
注意 : 'a'是字符型常量,而"a"是字符串型常量,二者是不同的。
C 语言规定,在每个字符串型常量的结尾加一个字符串结束标志,以便系统据此判断字符串是否结束。C语言规定以字符'\0'作为字符串结束标志。
void test_str(){
/* 打印字符串常量 */
printf("%s\n", "Hello World"); // 双引号引起的内容中会带着字符串结束标志 '\0'
// 双引号会返回字符串的首字符的地址编号
// %s输出时 遇到\0 结束输出
printf("sizeof=%d\n", sizeof("hello world"));
printf("%s\n", "hello\0world");
printf("%s\n", "\0hello world");
}
void test_str_v2(){
/* 打印字符串变量 */
char str[] = "Hello World";
printf("%s\n", str);
printf("sizeof = %d\n", sizeof(str));
str[0] = 'x';
printf("%s\n", str);
}
int main() {
printf("Hello world\n");
test_str();
printf("===========================\n");
test_str_v2();
// system("pause");
return 0;
}
4. 数据的输入和输出
4.1 数据的输入
scanf 函数的原理多种数据类型混合输入;C 语言未提供输入/输出关键字,其输入和输出是通过标准函数库来实现的.C 语言通过scanf
函数读取键盘输入,键盘输入又被称为标准输入。当scanf函数读取标准输入时,如果还没有输入任何内容,那么 scanf 函数会被卡住(专业用语为阻塞).下面来看一个例子。
#include <stdio.h>
int main() {
int i =10;
char c ='a';
scanf("%d", &i);
printf("%d\n",i);
scanf("%c", &c);
printf("%c\n",c);
}
为什么执行第二次的数据的时候不会阻塞等待输入呢, 因为此时内存中还存在数据(是第一次输入的回车键\n
),会直接将数据进行读取不会阻塞;
解决,进行数据的行缓冲;当在输入和输出中遇到换行符时,将执行真正的 IO 处理操作,这时,我们输入的字符先存放到缓冲区中,等按下回车键换行时才进行实际的 IO 操作。典型代表是标准输入缓冲区 ( stdin ) 和标准输出缓冲区 ( stdout ) , printf 使用的是 stdout。
解决后的代码
#include <stdio.h>
int main() {
int i =10;
char c ='a';
scanf("%d", &i);
printf("%d\n",i);
fflush(stdin); // 清空标注输入缓冲区
scanf("%c", &c);
printf("c=%c\n",c);
}
如果第二个scanf函数为scanf("%d",&i),那么依然会发生阻塞,因为scanf 函数在读取整型数、浮点数、字符串(后面介绍数组时讲解字符串)时,会忽略'\n'(回车符)、空格符等字符(忽略是指scanf函数执行时会首先删除这些字符,然后再阻塞) . scanf 函数匹配一个字符时,会在缓冲区删除对应的字符.因为在执行scanf("%c",&c)语句时,不会忽略任何字符,所以scanf("%c",&c)读取了还在缓冲区中残留的'\n'。
多种数据类型混合输入
当我们让 scanf 函数一次读取多种类型的数据时,对于字符型数据要格外小心,因为当一行数据中存在字符型数据读取时,读取的字符并不会忽略空格和\n
(回车符),所以使用方法,如下例所示。编写代码时,我们需要在%d与%c之间加入一个空格.输入格式和输出效果如下图所示, scanf函数匹配成功了4个成员,所以返回值为4,我们可以通过返回值来判断scanf函数匹配成功了几个成员,中间任何有一个成员匹配出错,后面的成员都会匹配出错。
#include <stdio.h>
int main() {
int i, ret;
char c;
float f;
ret = scanf("%d %c%f", &i, &c, &f); // 要在%c之前加个空格
printf("i=%d,c=%c,f=%5.2f\n", i, c, f);
return 0;
}
4.2 数据的输出
printf 函数可以输出各种类型的数据,包括整型、浮点型、字符型、字符串型等,实际原理是printf 函数将这些类型的数据格式化为字符串后,放入标准输出缓冲区,然后将结果显示到屏幕上.
语法格式
#include <stdio.h>
printf("XXXXXXX")
printf 函数根据 format 给出的格式打印输出到 stdout 和其他参数中。
int age = 21;
printf("Hello %s, you are %d years old\n", "Bob", age)
// >>> Hello Bob, you are 21 years old
代码 | 格式 |
---|---|
%c | 字符 |
%d | 带符号整数 |
%f | 浮点数 |
%s | 一串字符 |
%u | 无符号整数 |
%x | 无符号十六进制,用小写字母 |
%X | 无符号十六进制,用大写字母 |
%p | 一个指针 |
%% | 一个 % 符号 |
位于 % 和格式化命令之间的一个整数被称为最小字段宽度说明符,通常会加上空格来控制格式。
-
用
%f
精度修饰符指定想要的小数位数。例如,%5.2f
会至少显示5位数字并带有2位小数的浮点数。 -
用
%s
精度修饰符简单地表示一个最大的长度,以补充句点前的最小字段长度.
printf 函数的所有输出都是右对齐的,除非在%符号后放置了负号。例如, %-5.2f
会显示 5 位字符、2 位小数位的浮点数并且左对齐。
int main() {
int i = 10;
float f = 96.3f; // f 表示单精度,可选
printf("student number =%3d score %5.2f\n",i,f);
printf("student number =%-3d score %5.2f\n",i,f);
printf("%10s","hello");
}
执行结果如下图所示,可以看到整型数10在不加负号时靠右对齐,加负号时靠左对齐,%10s代表字符串共占用10个字符的位置.因为 printf 函数默认靠右对齐,所以"hello"字符串相对于左边的起始位置有5个空格的距离.掌握这些内容后,在做OJ作业时,就会很容易掌握打印格式的控制。
5. 运算符
5.1 算数运算符
作用:用于处理四则运算
算术运算符包括以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | -3 | -3 |
+ | 加 | 10 + 5 | 15 |
- | 减 | 10 - 5 | 5 |
* | 乘 | 10 * 5 | 50 |
/ | 除 | 10 / 5 | 2 |
% | 取模(取余) | 10 % 3 | 1 |
++ | 前置递增 | a=2; b=++a; | a=3; b=3; |
++ | 后置递增 | a=2; b=a++; | a=3; b=2; |
-- | 前置递减 | a=2; b=--a; | a=1; b=1; |
-- | 后置递减 | a=2; b=a--; | a=1; b=2; |
示例1:
//算术运算符 + - * /
void test01()
{
int a = 10;
int b = 3;
printf("a + b = %d\n", a + b); //13
printf("a - b = %d\n", a - b); //7
printf("a * b = %d\n", a * b); //30
printf("a / b = %d\n", a / b); //3 两个正数相除 结果也是正数,小数部分舍弃掉
int a2 = 10;
int b2 = 20;
// C 语言中不存在异常检测的关键字, 因此会直接退出;不会执行后续代码;
printf("a2 / b2 = %d\n", a2 / b2); // 0
int a3 = 10;
int b3 = 0;
//printf("a3 / b3 = %d\n", a3 / b3);//error 除数不可以为0
//两个小数之间 是可以做除法运算的
double d1 = 0.5;
double d2 = 0.25;
printf("d1 / d2 = %lf\n", d1 / d2);
}
总结:在除法运算中,除数不能为0;
示例2:
//取模 取余 运算
void test02()
{
int a1 = 10;
int b1 = 3;
printf("10 %% 3 = %d\n", a1 % b1);
int a2 = 10;
int b2 = 20;
printf("a2 %% b2 = %d\n", a2 % b2); // 10
int a3 = 10;
int b3 = 0;
//printf("a3 %% b3 = %d\n", a3 % b3); //error
double d1 = 5.3;
double d2 = 1.1;
//对于小数而言,是不可以取余数
//printf("d1 %% d2 = %lf\n", d1 %d2);//error
}
总结:只有整型变量可以进行取模运算
示例3:
void test04()
{
//后置递增
int a = 10;
a++; // a = a + 1;
printf("a = %d\n", a);
//前置递增
int b = 10;
++b; // b = b+1;
printf("b = %d\n", b);
//作为独立语句,前置和后置没有区别
//当进行混合运算时,才有区别
//前置++ 先对变量 进行 ++ 再 计算表达式
int a3 = 10;
int b3 = ++a3 * 10; // a3 = a3 + 1 b3 = a3 * 10
printf("a3 = %d\n", a3); //11
printf("b3 = %d\n", b3); //110
//后置++ 先计算表达式 再对变量进行++运算
int a4 = 10;
int b4 = a4++ * 10;
printf("a4 = %d\n", a4); //11
printf("b4 = %d\n", b4); //100
}
总结:前置递增先对变量进行++,再计算表达式,后置递增相反
5.2 赋值运算
作用:用于将表达式的值赋给变量
赋值运算符包括以下几个符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
= | 赋值 | a=2; b=3; | a=2; b=3; |
+= | 加等于 | a=0; a+=2; | a=2; |
-= | 减等于 | a=5; a-=3; | a=2; |
*= | 乘等于 | a=2; a*=2; | a=4; |
/= | 除等于 | a=4; a/=2; | a=2; |
%= | 模等于 | a=3; a%2; | a=1; |
示例:
void test01()
{
//赋值 运算 将=右边的值 赋给=左边
int a = 10;
a = 100;
int b = a;
b = a;
//左值 能够在=左边的值 成为左值
//右值 只能在=右边的值 成为右值
// +=
a = 10;
a += 2; // a = a + 2;
printf("a = %d\n", a); // 12
// -=
a = 10;
a -= 2; // a = a - 2;
printf("a = %d\n", a); //8
// *=
a = 10;
a *= 2; // a = a * 2;
printf("a = %d\n", a); // 20
// /=
a = 10;
a /= 2; // a = a / 2;
printf("a = %d\n", a); // 5
// %=
a = 10;
a %= 2; // a = a % 2;
printf("a = %d\n", a); // 0
}
void test02()
{
//注意事项:在做+= -= *=....中 =右边的表达式要看成一个整体
int num = 10;
num *= 3 + 5; // num = num * (3 + 5)
printf("num = %d\n", num); // 80
}
5.3 比较运算符
作用:用于表达式的比较,并返回一个真值或假值
比较运算符有以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
== | 相等于 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 1 | 1 |
示例:
void test01()
{
int a = 10;
int b = 20;
//在C中 0 代表假 非零 代表真
printf("a==b %d\n", a == b); //0
printf("a!=b %d\n", a != b); //1
printf("a>b %d\n", a > b); //0
printf("a<b %d\n", a < b); //1
printf("a>=b %d\n", a >= b); //0
printf("a<=b %d\n", a <= b); //1
}
注意:C语言的比较运算中,真 用数字
1
来表示, 假 用数字0
来表示。
5.4 逻辑运算符
作用:用于根据表达式的值返回真值或假值
逻辑运算符有以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
! | 非 | !a | 如果a为假,则!a为真; 如果a为真,则!a为假。 |
&& | 与 | a && b | 如果a和b都为真,则结果为真,否则为假。 |
|| | 或 | a || b | 如果a和b有一个为真,则结果为真,二者都为假时,结果为假。 |
示例1:逻辑非
//逻辑非 !
void test01()
{
int a = 10;
printf("!a = %d\n", !a); //0
printf("!!a = %d\n", !!a); //1
printf("%d\n", !100); // 0
printf("%d\n", !!100); // 1
printf("%d\n", !- 100); // 0
//非零都是真!!!
}
总结: 真变假,假变真
示例2:逻辑与
//逻辑与
void test02()
{
//同真为真 一假为假
int a = 10;
int b = 20;
printf(" a && b = %d\n", a && b); //1
a = 10;
b = 0;
printf(" a && b = %d\n", a && b); //0
a = 0;
b = 0;
printf(" a && b = %d\n", a && b); //0
//注意:只有表达式1 为真 ,才会判断表达式2 短路特性
4 < 3 && printf("hello1\n");
4 > 3 && printf("hello2\n");
}
总结:逻辑与运算符总结: 同真为真,其余为假
示例3:逻辑或
void test03()
{
// 同假为假 一真为真 ||
int a = 10;
int b = 10;
printf("a || b = %d\n", a || b); // 1
a = 0;
b = 10;
printf("a || b = %d\n", a || b); // 1
a = 0;
b = 0;
printf("a || b = %d\n", a || b); // 0
//注意:只有表达式1为假 才判断表达式2 短路特性
4 < 3 || printf("hello1\n"); //执行hello1
4 > 3 || printf("hello2\n"); //不执行 hello2
}
逻辑或运算符总结:同假为假,其余为真
6. 程序的流程结构
6.1 选择结构
选择结构主要有两种语法,if
和switch
6.1.1 if 语句
选择结构主要是if-else
结构语句;
//单行 if语句
void test01()
{
//如果输入的数据 大于600分,认为考试一本大学,进行输出
int score = 0;
printf("请输入一个分数:\n");
scanf("%d", &score);
printf("您输入的分数为:%d\n", score);
//语法: if(满足条件){ 满足条件成立,执行的语句 }
if (score > 600)
{
printf("考上了一本大学!\n");
}
}
//多行if语句
void test02()
{
//如果输入的数据 大于600分,认为考试一本大学,输出,没有考上一本,也输出
int score = 0;
printf("请输入一个分数:\n");
scanf("%d", &score);
printf("您输入的分数为:%d\n", score);
if (score > 600)
{
printf("考上了一本大学!\n");
}
else //未满足条件 进入代码体
{
printf("未考上一本大学\n");
}
}
注意:if 条件表达式后不要加分号
//多条件if语句
void test03()
{
//如果输入的数据 大于600分,认为考试一本大学,大于500 ,考上二本,大于400 考上三本,小于等于400,没考上本科
int score = 0;
printf("请输入一个分数:\n");
scanf("%d", &score);
printf("您输入的分数为:%d\n", score);
if (score > 600)
{
printf("考上了一本大学!\n");
}
else if (score > 500)
{
printf("考上了二本大学!\n");
}
else if (score > 400)
{
printf("考上了三本大学!\n");
}
else
{
printf("没有考上本科!\n");
}
}
嵌套if语句:在if语句中,可以嵌套使用if语句,达到更精确的条件判断;
案例需求:
- 提示用户输入一个高考考试分数,根据分数做如下判断
- 分数如果大于600分视为考上一本,大于500分考上二本,大于400考上三本,其余视为未考上本科;
- 在一本分数中,如果大于700分,考入北大,大于650分,考入清华,大于600考入人大。
//if语句 嵌套 if语句
void test04()
{
int score = 0;
printf("请输入一个分数:\n");
scanf("%d", &score);
printf("您输入的分数为:%d\n", score);
//考上一本了,如果是大于700分,认为考上北大,大于650,考上清华,其余,考上人大
if (score > 600)
{
printf("考上了一本大学!\n");
if (score > 700)
{
printf("恭喜你考入了北大!\n");
}
else if (score > 650)
{
printf("恭喜你考入了清华!\n");
}
else
{
printf("恭喜你考入了人大!\n");
}
}
else if (score > 500)
{
printf("考上了二本大学!\n");
}
else if (score > 400)
{
printf("考上了三本大学!\n");
}
else
{
printf("没有考上本科!\n");
}
}
注意事项
//if语句的注意事项
void test05()
{
//1、不要在if语句的后面加 分号;
int a = 10;
int b = 20;
//if (a > b); //如果加入分号,后面的代码肯定会执行
//{
// printf("a > b\n");
//}
//2、if语句实现体中如果不加{},只能识别最近的一行代码
//if (a > b)
// printf("a > b\n");
//printf("a > b\n");
//3、做对比操作的时候,不要写成 = ,而是用 ==
int num = 5;
if (num = 10) //error 不要写成 =
{
printf("num == 10\n");
}
else
{
printf("num != 10\n");
}
}
6.1.2 switch 语句
作用:执行多条件分支语句
语法:
switch(表达式)
{
case 结果1:执行语句;break;
case 结果2:执行语句;break;
...
default:执行语句;break;
}
示例:
void test01()
{
//给电影评分
//10 ~ 9 经典
//8 ~ 7 非常好
//6 ~ 5 一般
//5以下 烂片
int score = 0;
printf("请给电影打分:\n");
scanf("%d", &score);
printf("您给的分数是:%d\n", score);
switch (score) //switch中的表达式类型,只能是整型或者字符型
{
case 10:
//printf("经典\n");
//break; //利用break结束分支
case 9:
printf("经典\n");
break;
case 8:
//printf("非常好\n");
//break;
case 7:
printf("非常好\n");
break;
case 6:
//printf("一般\n");
//break;
case 5:
printf("一般\n");
break;
default: //默认的分支
printf("烂片\n");
break;
}
//总结:与if语句比较,对于多条件判断时候,switch结构比较清晰,执行效率高, 缺点判断区间不方便
}
注意1:switch语句中表达式类型只能是整型或者字符型
注意2:case里如果没有break,那么程序会一直向下执行
总结:与if语句比,对于多条件判断时,switch的结构清晰,执行效率高,缺点是switch不可以判断区间
6.1.3 三目运算符
作用: 通过三目运算符实现简单的判断
语法:表达式1 ? 表达式2 :表达式3
解释:
如果表达式1的值为真,执行表达式2,并返回表达式2的结果;
如果表达式1的值为假,执行表达式3,并返回表达式3的结果。
示例:
void test01()
{
int a = 10;
int b = 20;
int c = 0;
c = a > b ? a: b;
printf("a = %d\n", a); //10
printf("b = %d\n", b); //20
printf("c = %d\n", c); //20
}
总结:和if语句比较,三目运算符优点是短小整洁,缺点是如果用嵌套,结构不清晰
6.2 循环结构
6.2.1 while 语句
作用:满足循环条件,执行循环语句
语法: while(循环条件){ 循环语句 }
解释:只要循环条件的结果为真,就执行循环语句
示例:
//while循环
void test01()
{
int num = 0;
while (num < 10) // 不满足条件的时候退出循环
{
printf("num = %d\n", num);
//循环必须得有一个退出的条件,否则会进入死循环
num++;
}
}
注意:在执行循环语句时候,程序必须提供跳出循环的出口,否则出现死循环
6.2.2 do...while循环语句
作用: 满足循环条件,执行循环语句
语法: do{ 循环语句 } while(循环条件);
注意:与while的区别在于do...while会先执行一次循环语句,再判断循环条件
示例:
void test01()
{
int num = 0;
//while先判断循环条件,如果满足条件,在执行循环体代码
//while (num > 10)
//{
// printf("num = %d\n", num);
// num++;
//}
//do while 与while区别在于 dowhile会先执行一次循环体的代码,然后在判断条件
do
{
printf("num = %d\n", num);
num++;
} while (num > 10);
}
总结:与while循环区别在于,do...while先执行一次循环语句,再判断循环条件
6.2.3 for 循环语句
作用: 满足循环条件,执行循环语句
语法: for(起始表达式;条件表达式;末尾循环体) { 循环语句; }
示例:
void test01()
{
//for(起始表达式 ; 条件表达式; 末尾循环体) { 循环代码}
for (int i = 0; i < 10; i++)
{
printf("%d\n", i);
}
//for循环中的3个内容可以省略的 ,分号不可以省略
//int j = 0;
//for (;;)
//{
// if (j == 10)
// {
// break;
// }
// printf("%d\n", j);
// j++;
//}
}
注意:for循环中的表达式,要用分号进行分隔
总结:while , do...while, for都是开发中常用的循环语句,for循环结构比较清晰,比较常用
6.2.4 嵌套循环
作用: 在循环体中再嵌套一层循环,解决一些实际问题
例如我们想在屏幕中打印如下图片,就需要利用嵌套循环
示例:
void test01()
{
//外层循环控制行 i ,内层循环控制列 j
for (int i= 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
printf("* ");
}
printf("\n");
}
}
6.3 跳转结构
6.3.1 break语句
作用: 用于跳出选择结构或者循环结构
break 使用的时机:
- 出现在switch条件语句中,作用是终止case并跳出switch
- 出现在循环语句中,作用是跳出当前的循环语句
- 出现在嵌套循环中,跳出最近的内层循环语句
示例1:
void test01()
{
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
printf("%d\n",i);
}
}
示例2:
void test02()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (j == 5)
{
break;
}
printf("* ");
}
printf("\n");
}
}
6.3.2 continue 语句
作用:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
示例:
//continue
void test03()
{
//跳过本次剩余的代码,执行下一次的循环
for (int i = 0; i < 100; i++)
{
if (i % 2 == 0)
{
continue; //不会退出循环,而break 会退出循环
}
printf("i = %d\n", i);
}
}
注意:continue并没有使整个循环终止,而break会跳出循环
6.3.3 goto语句
作用:可以无条件跳转语句,考研过程使用较少;
语法: goto 标记;
解释:如果标记的名称存在,执行到goto
语句时,会跳转到标记的位置
示例:
//goto 无条件跳转语句
//由于容易让程序混乱,不建议用
void test04()
{
printf("1\n");
printf("2\n");
goto FALG;
printf("3\n");
printf("4\n");
FALG:
printf("5\n");
printf("6\n");
}
注意:在程序中不建议使用goto语句,以免造成程序流程混乱
度过大难,将有大成;
继续努力,终有大成;