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;
}



image-20240725161807330

2.2 注释

两种格式

  1. 单行注释:

// 描述信息
通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明

  1. 多行注释:

/* 描述信息 */
通常放在一段代码的上方,对该段代码做整体说明

提示:编译器在编译代码时,会忽略注释的内容

3. 数据类型与变量

image-20240725163115222

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_agestudentAge作为变量名。‌

  • 常量使用大写命名:‌常量的命名应全部大写,‌例如PI_VALUE。‌

  • 指针和宏的命名:‌指针变量名可以加上前缀表示,‌如int *pStudentAge;,‌宏定义应使用全大写,‌如#define MAX_STUDENTS 100。‌

  • 避免使用关键字:‌变量名不应与C语言的关键字相同,‌如int case = 12;是错误的,‌因为case是C语言的关键字。‌

  • 全局变量和函数的命名:‌全局变量或函数应加上范围限定符(‌如模块名缩写)‌以避免命名冲突,‌例如g_pFileLog表示全局变量。‌

  • 缩写和一致性:‌如果使用缩写,‌应在整个系统中保持一致,‌并注明其意思。‌

遵循这些规范可以使代码更易于阅读和维护,‌提高代码的可读性和可维护性。

3.4 常量

作用:用于记录程序中不可更改的数据

C语言中的常量大概有以下五种表现形式

  1. 数值常量(整数型常量(整数) 、实数型常量(小数))

  2. 字符常量 'a' 'b' 'c' '\n' '\t'

  3. 字符串常量 "hello world"

  4. #define 宏常量: #define 常量名 常量值

    • 通常在文件上方定义,表示一个常量

    • 在程序中使用的时候会进行文本替换,因此最好不要在宏中定义表达式。image-20240725194001672

  5. 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;
}

image-20240725194442098

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;
}

image-20240725195358065

3.7 字符串

字符串型常量是由一对双引号括起来的字符序列。

注意 : 'a'是字符型常量,而"a"是字符串型常量,二者是不同的。

C 语言规定,在每个字符串型常量的结尾加一个字符串结束标志,以便系统据此判断字符串是否结束。C语言规定以字符'\0'作为字符串结束标志。

image-20240725210000159

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;
}

image-20240725210915177

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);
}

image-20240726154032768

为什么执行第二次的数据的时候不会阻塞等待输入呢, 因为此时内存中还存在数据(是第一次输入的回车键\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);
}

image-20240726154937828

如果第二个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;
}

image-20240726162008770

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作业时,就会很容易掌握打印格式的控制。

image-20240726171828210

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 选择结构

选择结构主要有两种语法,ifswitch

6.1.1 if 语句

选择结构主要是if-else结构语句;

image-20240727102632999

image-20240727102920414

image-20240727102954004

//单行 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 语句

image-20240727104424752

作用:满足循环条件,执行循环语句

语法: 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会先执行一次循环语句,再判断循环条件

img

示例:

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 嵌套循环

作用: 在循环体中再嵌套一层循环,解决一些实际问题

例如我们想在屏幕中打印如下图片,就需要利用嵌套循环

1541676003486

示例:

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语句,以免造成程序流程混乱

度过大难,将有大成;

继续努力,终有大成;

posted @ 2024-07-27 12:07  紫青宝剑  阅读(23)  评论(0编辑  收藏  举报