嵌入式课程笔记_01_STDC01_20190303

01_STDC01

day1: Linux操作系统和文件系统 、 Linux常见命令

STDC01_day01_01-Linux操作系统和文件系统.ts

Linux操作系统的一种主要的使用方法是通过终端软件
终端里只能使用键盘不能使用鼠标
终端里通过输入命令控制计算机完成任务
clear命令可以清除终端窗口里所有文字内容
操作系统中用来管理文件的部分叫文件系统
所有文件系统都通过分组方式管理文件,一个分组里可以包含任意多个文件
一个分组里的文件还可以再次分组
我们把文件分组叫做文件夹或目录
Linux的文件系统里有一个大的文件分组,这个分组里包含所有文件
这个文件分组叫做根目录
可以使用/表示根目录

                           /
        abc                         def
pqr     vbn     iop             xyz      tuy

我们把两个目录之间的直接包含关系叫做父子关系。其中距离根目录近的叫父目录,另外一个叫子目录
路径用来表示文件夹或文件所在的位置
路径表示从某个目录开始到某个目录或文件为止的路线

路径分为绝对路径相对路径
这两种路径的起点不同

绝对路径固定把根目录作为起点

STDC01_day01_02-文件系统.ts

/abc/vbn 绝对路径表示vbn的位置
绝对路径一定以/做开头

相对路径可以把任何目录作为起点
相对路径里不需要包含起点位置
相对路径里固定使用..表示从下向上走一步
相对路径里使用.表示原地踏步
../../abc/vbn

终端窗口里一个把任何目录设置成当前目录,当前目录是所有相对路径的起点
当前目录的位置可以随时改变

STDC01_day01_03-Linux常见命令01.ts

pwd命令可以用来查看当前目录的位置
cd命令可以用来设置当前目录的位置
使用方法如下
cd 目录路径

ls命令可以用来查看一个目录的内容
使用方法如下
ls 目录路径
ls / 查看根目录内容
ls .. 查看父目录内容
如果省略目录路径就可以查看当前目录里的内容
使用-a选项可以查看目录里的所有内容
使用-l选项可以查看每个内容的详细信息
这两个选项可以合并成-al

STDC01_day01_04-Linux常见命令02.ts

touch命令可以用来创建新的文件
使用方法如下
touch 文件路径
如果文件已经存在就把文件的最后修改时间设置成执行touch命令的时间

rm命令可以用来删除文件
使用方法如下
rm 文件路径

mkdir命令可以用来创建目录
使用方法如下
mkdir 目录路径
这个命令要求这个目录还不存在,但是它的父目录必须已经存在
使用-p选项可以把路径中所有不存在的目录都创建出来
rm也可以用来删除目录,这个时候需要使用-r选项
使用方法如下
rm -r 目录路径

STDC01_day01_05-vi编辑器01.ts

vi是Linux系统里用来记录文字信息的工具
vi只能在终端窗口里使用(不能使用鼠标)
vi的功能分成三组,任何时候只能使用其中一组
vi里包含三种工作模式,一种工作模式对应一组功能
任何时候只能处于一种工作模式下
三种工作模式分别是正常模式,插入模式和命令模式

正常模式下可以执行简单命令
插入模式下可以修改文字内容
命令模式下可以执行复杂命令

每当进入vi的时候一定处于正常模式

不同模式之间可以互相转换
正常模式下输入i可以进入插入模式
正常模式下输入:可以进入命令模式
任何时候按esc键都可以进入正常模式

可以采用如下命令启动vi
vi 文件路径

可以采用两种方法退出vi
1.在命令模式下输入q!(丢失所有没有保存的修改)
2.在命令模式下输入wqx(先保存所有修改然后退出)

命令模式下输入w命令就可以只保存所有修改而不需要退出vi

STDC01_day01_06-vi编辑器02.ts

正常模式下输入nyy命令(n代表一个整数,如果是1可以省略),这个命令可以把当前光标所在行开始的连续n行拷贝到剪切板上。

正常模式下输入np命令(n代表一个整数,如果是1可以省略),这个命令可以把剪切板上的文字内容在光标所在行下面连续粘贴n次

正常模式下输入ndd命令(n代表一个整数,如果是1可以省略),这个命令可以把当前光标所在行开始的连续n行剪切到剪切板上

命令模式下输入set nu命令可以让vi显示每行的行号

gVim是Windows里的vi

练习
假设要开发一个叫做BankATM的系统,这个系统分成两个部分(server和client)
要求设计一组目录把系统的所有文件和其他文件分开保存
系统中两个部分的文件也不要混在一起

mkdir BankATM
mkdir BankATM/client
mkdir BankATM/server

预习:
​ 1.C语言程序基本结构
​ 2.printf标准函数
​ 3.变量

day2: 编写第一个C程序 、 变量的基本使用

STDC01_day02_01-编写第一个C程序01.ts

C语言程序的绝大部分内容应该记录在以.c作为扩展名的文件里,这种文件叫做C语言程序的源文件
C语言程序里还包括以.h作为扩展名的文件,这种文件叫做C语言的头文件

/CSD1702/biaoc/day02 vi 01demo.c

C语言程序里可以直接使用数字和加减乘除符号(*代表乘法/代表除法)

C语言里每个计算步骤最后都必须使用分号作为结尾

用分号结尾的一个计算步骤叫做一条语句

{4000 - 2000;}

C语言中绝大多数语句都应该写在大括号里面

C语言里大括号可以用来代表一个**函数(**目前可以认为函数就是一组语句)
每个函数都必须有自己的名字,任何两个函数的名字不能相同

abc(){4000 - 2000;}

C语言中规定任何程序里必须包含一个叫做main的函数,这个函数叫做主函数
整个程序从主函数的第一条语句开始执行,当主函数里最后一条语句结束后整个程序结束

main(){4000 - 2000;}

函数在结束后可以用一个数字表示它的工作结果,这个数字叫做函数的返回值
主函数应该有一个返回值,如果返回值是0表示程序希望计算机认为它正常结束了,如果返回值不是0就表示程序希望计算机认为它出问题

STDC01_day02_02-编写第一个C程序02.ts

main(){4000 - 2000;return 0;}

C语言程序里预先保留了几十个英文单词,它们叫做关键字
每个关键字都有特定的用途,不能随意使用

return就是一个关键字
return关键字有两个用途,主要用途是用来结束函数的执行,辅助用途是指定返回值的数值

计算机里根据不同数字在某个方面的区别把数字分成几组,每组叫做一个数据类型
每个数据类型都有自己的名字
整数类型是一种数据类型,它的名字是int
这个数据类型包含几乎所有不带小数点的数字

程序中使用的所有数字都必须有数据类型
程序中使用的不带小数点的数字默认都是整数类型的

如果函数有返回值就必须把返回值的类型名称写在函数前面

int main(){
	4000 - 2000;
	return 0;
}

基本编码规范
1.一行最多包含一条语句
2.同级别的语句最左边一列应该上下对齐
3.尽量使用空格和空行让程序看起来更舒展

STDC01_day02_03-编写第一个C程序03.ts

C语言程序中通常会包含预处理指令
预处理指令以#做开头,不是以;做结尾
标准C阶段遇到的预处理指令都可以把文件里的内容替换成其他内容

#include是一个预处理指令,它可以把一个头文件的内容包含到当前文件里
在这个预处理指令中需要使用相对路径表示被包含头文件的位置
把相对路径包含在<>中间就表示用系统中预先规定好的一组目录依次作为起点查找头文件
把相对路径包含在""中间就表示首先以当前文件所在目录作为起点查找头文件然后再以系统中预先规定好的一组目录依次作为起点查找

C语言可以在程序中加入文字性的说明信息
这些信息必须加入到注释区域
计算机会直接忽略注释区域里的所有内容
单行注释以//做开头一直到行尾
多行注释以/*做开头,以*/做结尾

STDC01_day02_04-编写第一个C程序04.ts

C语言程序中经常需要使用名称区分不同内容
这些名称叫做标识符
标识符最好采用英文单词编写
标识符编写规则
1.第一个字符可以是英文字母或者下划线
2.后面的每个字符可以是英文字母,下划线或阿拉伯数字
3.大小写不同的标识符是不同的标识符(大小写敏感)
4.关键字不可以作为标识符使用
5.标识符的长度没有限制,但是计算机只会截取前面的一部分使用
6.标识符应该采用驼峰方式下划线方式书写

编译器可以把写好的程序翻译成计算机认识的格式
gcc是Linux系统里最常见的C语言编译器
MinGW是Windows里的gcc

Linux系统中进行C语言程序开发的基本步骤
1.使用vi编写源文件和头文件
2.使用gcc命令把所有源文件翻译成计算机认识的格式
3.最后使用./a.out做命令执行得到的结果文件

gcc编译器的工作步骤
1.处理所有预处理指令
2.把第一步的结果翻译成计算机认识的格式(编译)
3.把第二步的结果合并成可执行文件(链接)

STDC01_day02_05-编写第一个C程序05.ts

gcc选项介绍
-E 只处理预处理指令
-c 只处理预处理和编译工作
处理结果是以.o作为扩展名的目标文件
-o 用来决定得到的新文件名称
-std=c89/-std=c99 决定采用什么版本进行编译
​ 默认采用c89

C语言里包含一组标准函数,每个标准函数用来解决一个常见问题
每个标准函数都有自己的名字,不同标准函数的名字不同
可以在程序中编写函数调用语句使用标准函数

printf标准函数可以把程序里的数字显示在屏幕上
为了使用这个标准函数需要包含stdio.h头文件

STDC01_day02_06-编写第一个C程序06.ts

可以在双引号里使用占位符把数字转移到双引号后面
双引号后面的数字可以是编写程序的时候还不知道的数字
不同占位符需要和不同类型的数字配合使用,
%d这个占位符用来和整数类型数字配合使用
可以在一条语句里使用多个占位符,这个时候就需要在双引号后面提供多个数字。
​ 数字的个数和占位符的个数一样。
计算机会用双引号后面的数字依次替换双引号里面的数字,然后再显示

STDC01_day02_07-变量的基本使用01.ts

/CSD1702/biaoc/day02 03printf.c

/*
	printf标准函数练习
*/
#include <stdio.h>
int main(){
	printf("4000 - 1000 = 3000\n");
	printf("%d - %d = %d\n",4000,1000,4000 - 1000);
	return 0;	
}
结果:
4000 - 1000 = 3000
4000 - 1000 = 3000

程序中使用的所有数字都必须记录在内存
内存由大量的字节构成的,每个字节可以单独记录一个数字
每个字节有一个编号,不同字节的编号不同,这个编号叫做字节的地址
所有字节的地址从0开始向上递增
字节地址有前后方向,地址小的在前地址大的在后

可以把几个相邻字节合并成一个整体记录一个数字

可以把内存里用来记录一个数字的所有字节叫做一个存储区
一个存储区只能记录一种类型的数字
存储区也有地址,它的地址是它所包含的字节中最前面的那个字节的地址

C语言程序中用变量代表存储区,对变量的操作实际就是对它所代表存储区的操作

变量在使用之前必须首先声明,变量声明语句用来声明变量

/CSD1702/biaoc/day02 04var.c

/*
	变量演示
*/
#include <stdio.h>
int main(){
	int num;	//变量声明语句
	return 0;
}

可以在一条语句里声明多个同类型变量

/*
	变量演示
*/
#include <stdio.h>
int main(){
	int num,num1;	//变量声明语句
	return 0;
}

STDC01_day02_08-变量的基本使用02.ts

可以向变量里放一个数字也可以从变量里获得一个数字

赋值语句可以向变量里放一个数字
赋值语句中需要使用赋值操作符(=)

赋值操作符左边的内容必须可以代表一个存储区(左值),变量就是一种左值
赋值操作符右边的内容必须可以当作数字使用

/*
	变量演示
*/
#include <stdio.h>
int main(){
	int num = 0,num1 = 0;	//变量声明语句
	num = 10;	//赋值语句
	num = 5 + 8;
	return 0;
}

可以在声明变量的时候立刻对变量进行赋值,这叫做变量的初始化
C语言里所有变量都应该初始化

可以直接在程序中把变量当数字使用,这个时候计算机会从变量里拿出数字然后再进行其他计算

/*
	变量演示
*/
#include <stdio.h>
int main(){
	int num = 0,num1 = 0;	//变量声明语句
	num = 10;	//赋值语句
	num = 5 + 8;
	num = 4;
	printf("num是%d\n",num);
	return 0;
}
结果:
num是4

变量名称既可以代表存储区也可以代表存储区里的数字,由环境决定

STDC01_day02_09-变量的基本使用03.ts

存储区的地址也可以代表存储区
可以在变量名称前使用符号&得到存储区的地址
可以在printf函数调用语句里使用使用%p作为占位符把地址数据显示在屏幕上

/CSD1702/biaoc/day02 05var.c

/*
	地址演示
*/
#include <stdio.h>
int main(){
	int num = 0;
	printf("&num是%p\n", &num);
	return 0;
}
结果:
&num是0028FF1C   //不同运行条件下变量存储的地址不同

变量可以用来代表一个固定的数字

双引号里和双引号外都不能有数字

/CSD1702/biaoc/day02 06var.c

/*
	变量练习
*/
#include <stdio.h>
int main(){
	int price1 = 4000, price2 = 1000;
	printf("%d - %d = %d\n",price1,price2,price1-price2);
	return 0;
}
结果:
4000 - 1000 = 3000

STDC01_day02_10-变量的基本使用04.ts

一个变量可以用来代表一组数字(变量在不同的时候代表不同的数字)

/CSD1702/biaoc/day02 07var.c

/*
	变量演示
*/
#include <stdio.h>
int main(){
	int num = 1;
	printf("%d ",num);
	num = num + 1;
	printf("%d ",num);
	num = num + 1;
	printf("%d ",num);
	num = num + 1;
	printf("%d ",num);
	num = num + 1;
	printf("%d\n ",num);
	return 0;
}
结果:
1 2 3 4 5 

1 X 9 = 9
2 X 8 = 16
3 X 7 = 21
3 X 6 = 24
5 X 5 = 25
一次显示一行
显示语句里不能有数字

/CSD1702/biaoc/day02 08var.c

/*
	变量练习
*/
#include <stdio.h>
int main(){
	int num = 1,ten = 10;
	printf("%d X %d = %d\n",num,ten - num,num * (ten - num));
	num = num + 1;
	printf("%d X %d = %d\n",num,ten - num,num * (ten - num));
	num = num + 1;
	printf("%d X %d = %d\n",num,ten - num,num * (ten - num));
	num = num + 1;
	printf("%d X %d = %d\n",num,ten - num,num * (ten - num));
	num = num + 1;
	printf("%d X %d = %d\n",num,ten - num,num * (ten - num));
	return 0;
}
结果:
1 X 9 = 9
2 X 8 = 16
3 X 7 = 21
4 X 6 = 24
5 X 5 = 25

day3: C语言数据类型 、 变量的输入和输出

STDC01_day03_01-C语言数据类型01.ts

字符类型名称char
字符类型里包含256个不同的整数,每个整数可以用来代表一个字符(例如’a’,’^'等)
这些整数和字符可以互相替代
ASCII码表中列出所有整数和字符的对应关系

'a'			97
'A'			65
'0'			48

ASCII码表里所有小写英文字母是连续排列的,并且’a’对应的整数最小,字母’z’对应的整数最大
ASCII码表里所有大写英文字母和阿拉伯数字字符也都符合这个规律

'd' - 'a'	等于	'D' - 'A'
'd' - 'a'	等于	'3' - '0'		等于	3 - 0  

字符类型里的所有字符被分成两组,每组包含128个
其中一组字符和整数之间的对应关系在所有计算机上都一样,它们对应的整数范围从0开始到127为止
另外一组字符和整数之间的对应关系在不同的计算机上可能不同,它们对应的整数有可能从-128到-1,也有可能从128到255

'\n'		换行字符(newline)      使光标下移一格
'\r'		回车字符(return)       使光标到行首

/CSD1702/biaoc/day03 01char.c

/*
	字符演示
*/
#include <stdio.h>
int main(){
    printf("abc\nde\n"
    printf("abc\rde\r");
    return 0;
}
结果:
abc
de
dec

特殊字符输入方法

'\''		代表字符'
'\"'		代表字符"
'\\'		代表字符\

短整数类型名称是short (2个字节)
这个类型里包含65536个不同的整数,其中一半是非负数,另外一半是负数。这些数字以数字0为中心向两边扩展

长整数类型名称是long (32位系统4个字节,64位系统8个字节)
这个类型里包含2的32次方个不同的整数,其中一半是非负数,另外一半是负数。这些数字以数字0为中心向两边扩展的。

整数类型名称是int
在我们的计算机上整数类型和长整数类型完全一样

以上类型统一叫做有符号类型
每个有符号类型有一个对应的无符号类型,无符号类型的名称是在对应的有符号类型名称前加unsigned(例如unsigned char,unsigned int等)

STDC01_day03_02-C语言数据类型02.ts

无符号类型和它对应的有符号类型所包含的整数个数一样,但是不包含负数

整数相关类型所包含的数字范围互相重叠并且逐渐扩大

程序中不带小数点的数字后加u表示数字的类型是无符号整数类型

C语言程序中使用浮点类型表示带小数点的数字
浮点类型分为单精度浮点类型双精度浮点类型
双精度浮点类型可以记录更多小数点后面的数位
单精度浮点类型的名称是float
双精度浮点类型的名称是double

程序中带小数点的数字默认是双精度浮点类型
如果带小数点的数字后加f就表示这个数字的类型是单精度浮点类型

STDC01_day03_03-C语言数据类型03.ts

C语言里允许程序员扩展新的数据类型
这些新的数据类型叫复合数据类型
复合数据类型需要先创建然后才能使用

C99规范里引入布尔类型
这个类型里只包含0和1两个整数,0叫做假,1叫做真
真和假都叫做布尔值

任何一个整数都可以当作布尔值使用,0当作布尔值使用的时候是假,其他整数当作布尔值使用的时候都是真

数据类型和占位符的对应关系

char和unsigned char		    %c
short					    %hd
unsigned short			    %hu
long						%ld
unsigned long				%lu
int  						%d          //将内存中二进制存的数字以int型显示出来
unsigned int				%u          //将内存中二进制存的数字以unsigned int型显示出来
float						%f或%g
double				        %f或%lg

%f%lf会保留小数点后面多余的0,%g和%lg不会保留

/CSD1702/biaoc/day03 02char.c

/*
	占位符演示
*/
#include <stdio.h>
int main(){
    printf("%f    %g\n",5.2f,5.2f);
    return 0;
}
结果:5.200000    5.2

STDC01_day03_04-C语言数据类型04.ts

不同数据类型的一个重要区别就是不同类型的存储区包含的字节个数不同
sizeof关键字可以用来计算一个存储区包含的字节个数

/CSD1702/biaoc/day03 03sizeof.c

/*
	sizeof关键字演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("sizeof(num)是%d\n",sizeof(num));
    printf("sizeof(int)是%d\n",sizeof(int));
    printf("sizeof(2 + 5)是%d\n",sizeof(2 + 5));    
    return 0;
}
结果:
sizeof(num)是4
sizeof(int)是4
sizeof(2 + 5)是4  

charunsigned char 1个字节
shortunsigned short 2个字节
intunsigned int 4个字节
longunsigned long 4个字节
float 4个字节
double 8个字节

sizeof小括号里可以写任何能当作数字使用的内容

/CSD1702/biaoc/day03 03sizeof.c

/*
	sizeof关键字演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("sizeof(num)是%d\n",sizeof(num));
    printf("sizeof(int)是%d\n",sizeof(int));
    printf("sizeof(2 + 5)是%d\n",sizeof(2 + 5));
    sizeof(num = 10);		//num = 10没有执行 num还是0
    printf("num是%d\n",num);
    return 0;
}
结果:
sizeof(num)是4
sizeof(int)是4
sizeof(2 + 5)是4
num是0

sizeof小括号里对任何存储区内容的修改不会真正生效

STDC01_day03_05-变量的输入和输出01.ts

scanf标准函数可以把用户在键盘上输入的数字记录到变量的存储区里
为了使用这个标准函数需要包含stdio.h头文件

/CSD1702/biaoc/day03 04scanf.c

/*
	scanf标准函数演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    scanf("%d",&num);
    printf("num是%d\n",num);
    return 0;
}
输入:4.2按回车健
结果:num是4

scanf函数调用语句里需要使用存储区的地址表示存储区
双引号里使用占位符表示存储区的类型

/CSD1702/biaoc/day03 04scanf.c

/*
	scanf标准函数演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("请输入一个数字:");
    scanf("%d",&num);
    printf("num是%d\n",num);
    return 0;
}
输入:6.9按回车健
结果:num是6

/CSD1702/biaoc/day03 04scanf.c

/*
	scanf标准函数演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("请输入一个数字:");
    scanf("ab%d",&num);
    printf("num是%d\n",num);
    return 0;
}
输入:45按回车健
结果:没有结果
输入:ab34按回车健
结果:num是ab34

不要在scanf函数调用语句的双引号里写不是占位符的内容

STDC01_day03_06-变量的输入和输出02.ts

可以在一条scanf函数调用语句里获得多个数字

/CSD1702/biaoc/day03 04scanf.c

/*
	scanf标准函数演示
*/
#include <stdio.h>
int main(){
    int num = 0,num1 = 0;
    printf("请输入两个数字:");
    scanf("%d%d",&num,&num1);
    printf("num是%d\n",num);
    printf("num1是%d\n",num1);
    return 0;
}
结果:
请输入两个数字:34 87      (两个数字间可以用空格或回车分开)
num是34
num1是87

如果用户输入的格式和程序中要求的格式不同就无法获得数字

练习:
编写程序从键盘得到一个浮点数作为圆的半径,计算圆的周长并把结果显示在屏幕上
根据半径计算周长的公式是
2 * 3.14 * 半径

/CSD1702/biaoc/day03 05circle.c

/*
	变量练习
*/
#include <stdio.h>
int main(){
    float radius = 0.0f;
    printf("请输入半径:");
    scanf("%g",&radius);
    printf("周长是%g\n",2 * 3.14f * radius);
    return 0;
}
结果:
请输入半径:5.2
结果:
周长是32.656

STDC01_day03_07-进制转换01.ts

一个字节可以分成八段,每段可以用来记录一个0或者1
要想把一个数字记录到一个字节里就必须首先把它拆分成8个0或者1
采用一组0或者1表示数字的方法叫二进制
任何数字既可以采用二进制方式表示也可以采用十进制方式表示
计算机里只能记录二进制方式表示的数字
二进制表示方式中每个数位有一个有一个编号,最右边数位的编号是0,向左依次递增
二进制表示方式中某个数位里的1单独代表一个数字,这个数字就是2的数位编号次方
二进制表示方式中如果两个相邻数位的内容一样则左边数位代表的数字是右边数位代表数字的2倍
用二进制表示的非负数符合以上规则
二进制加一的时候把数位0开始的连续多个1都变成0,把最右边的0变成1

STDC01_day03_08-进制转换02.ts

二进制表示的非负数转换成十进制的时候只需要把每个数位里的内容单独转换然后再求和

0000 0101	=	2的2次方 + 2的0次方
​			=	4 + 1
​			=	5

0010 1100	=	2的5次方 + 2的3次方 + 2的2次方
​			=	32 + 8 + 4
​			=	44

十进制表示的非负数转换成二进制的方法

12		*******0
6		******0
3		*****1
1		****1
0		****

转换结果是0000 1100

不断对原始数字进行除以2保留整数部分的操作得到一组数字,用其中每个数字除以2取余得到一个数位的内容,把所有数位的内容按照从后向前的顺序书写就得到转换结果

STDC01_day03_09-进制转换03.ts

负数的二进制和十进制之间不能直接转换,需要借助相反数

转换过程分三步:
1.首先根据原始数字得到相反数
2.把第一步得到的相反数进行转换
3.根据第二步的转换结果再计算相反数

把二进制表示方式中每个数位的内容变成相反内容然后再加一就得到相反数的二进制

0110 1101 (109的二进制)
1001 0010 + 1 = 1001 0011  (-109的二进制)
                0110 1100 + 1 = 0110 1101 (109的二进制)

-14

STDC01_day03_10-进制转换04.ts

-14
14
0000 1110 (14的二进制)
1111 0001 + 1 =1111 0010		(-14的二进制)

有符号类型数字最左边的二进制数位可以帮助判断数字的符号,这个数位叫做符号位
符号位是0表示数字是非负数,符号位是1表示数字是负数

1100 0101 (负数)
0011 1010 + 1 = 0011 1011 (得到相反数)
59
-59

STDC01_day03_11-进制转换05.ts

/CSD1702/biaoc/day03 06bit.c

/*
	二进制演示
*/
#include <stdio.h>
int main(){
    char ch = 300;
    int num = ch;
    printf("num是%d\n",num);
    return 0;
}
结果:
num是44

300的二进制是
0000 0000
0000 0000
0000 0001
0010 1100

ch是字符类型,只能保存一个字节
0010 1100

num是整数类型,可以保存四个字节
0000 0000
0000 0000
0000 0000
0010 1100

/CSD1702/biaoc/day03 06bit.c

/*
	二进制演示
*/
#include <stdio.h>
int main(){
    char ch = 300;
    int num = ch;
    printf("num是%d\n",num);
    ch = 128;
    num = ch;
    printf("num是%d\n",num);
    return 0;
}
结果:
num是44
num是-128

128在内存中的二进制
0000 0000
0000 0000
0000 0000
1000 0000

将128赋值给字符变量时 字符型变量有符号位
1000 0000

赋值给整数类型时填充符号位1
1111 1111
1111 1111
1111 1111
1000 0000
所以num是-128

练习:
编写程序从键盘得到一个0到127之间的整数,把它转换成二进制并把结果显示在屏幕上
八个二进制数位就够了
基础知识: 15 / 6 = 2
​ 15 % 6 = 3

/CSD1702/biaoc/day03 07bit.c

/*
	二进制练习
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("请输入一个数字:");
    scanf("%d",&num);
    printf("        %d\r",num % 2);
    num = num / 2;
    printf("       %d\r",num % 2);
    num = num / 2;
    printf("      %d\r",num % 2);
    num = num / 2;
    printf("    %d\r",num % 2);
    num = num / 2;
    printf("   %d\r",num % 2);
    num = num / 2;
    printf("  %d\r",num % 2);
    num = num / 2;
    printf(" %d\r",num % 2);
    num = num / 2;
    printf("%d\n",num % 2);
    return 0;
}

预习:
​ 1.八进制和十六进制
​ 2.操作符

day4: 运算符

STDC01_day04_01-进制转换06.ts

把二进制数字从右向左每三个数位分成一组,每组用一个0到7之间的数字替换,这个替换结果叫做八进制表示方式

0110 1011 01 101 011 153(八进制)

可以在程序中直接使用八进制方式表示数字,这个时候数字必须以0做开头
printf函数调用语句里使用%o做占位符可以把数字的八进制表示方式显示在屏幕上

/CSD1702/biaoc/day04 01bit.c

/*
	八进制和十六进制演示
*/
#include <stdio.h>
int main(){
    printf("%d    0%o\n",0153,0153);
    return 0;
}
结果:107    0153

把二进制数字从右向左每四个数位分成一组,每组用一个字符替换(用a到f之间的字母替换10到15之间的数字),这个替换结果叫做数字的十六进制表示方式

1100 1011 cb(十六进制)

可以在程序中直接使用十六进制方式表示数字,这个时候数字必须以0x做开头
可以使用%x%X做占位符把数字的十六进制方式显示在屏幕上
显示结果里不包含0x开头
补充:要想在显示十六进制的时候输出0x或者0X开头,可使用%#x或者%#X作为占位符,也可以在%x或者%X前自己加0x或者0X
%x做占位符的时候显示结果里所有字符都是小写
%X做占位符的时候显示结果里所有字符都是大写

/CSD1702/biaoc/day04 01bit.c

/*
	八进制和十六进制演示
*/
#include <stdio.h>
int main(){
    printf("%d    0%o\n",0153,0153);
    printf("%d    0x%x    0X%X",0xcb,0xcb,0xcb);
    return 0;
}
结果:
107    0153
203    0xcb    0XCB

STDC01_day04_02-运算符01.ts

操作符用来表示对数字的处理规则
根据操作符所需要配合的数字个数把操作符分成
单目操作符,双目操作符和三目操作符
加减乘除(+,-,*,/)都是双目操作符
如果参与除法计算的两个数字都是整数则计算结果保留整数部分

C语言里用%表示取余操作

赋值操作符=表示
赋值语句可以当作数字使用,这个数字就是赋值结束后存储区里的内容
可以在一条语句里使用多个赋值操作符,这个时候优先计算右边的操作符

/CSD1702/biaoc/day04 02opr.c

/*
	操作符演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    char ch = 0;
    num = ch = 300;
    printf("num是%d\n",num);
    return 0;
}
结果:
num是44

STDC01_day04_03-运算符02.ts

绝大多数双目操作符可以和赋值操作符合并成复合赋值操作符,例如+=,*=
复合赋值操作符会把双目操作符的计算结果记录到左边的存储区里

/CSD1702/biaoc/day04 02opr.c

/*
	操作符演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    char ch = 0;
    num = ch = 300;
    printf("num是%d\n",num);
    num += 6;
    printf("num是%d\n",num);
    num *= 2 + 3;			//num = num * (2 + 3);
    printf("num是%d\n",num);
    return 0;
}
结果:
num是44
num是50
num是250

复合赋值操作符的优先级和赋值操作符的优先级一样低

自增操作符(++)和自减操作符(--)都是单目操作符
它们都只能和存储区配合使用,它们可以把存储区的内容加一或者减一
它们各自有两种使用方法,一种是前操作(操作符写在存储区前面),另外一种是后操作(操作符写在存储区后面)

/CSD1702/biaoc/day04 02opr.c

/*
	操作符演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    char ch = 0;
    num = ch = 300;
    printf("num是%d\n",num);
    num += 6;
    printf("num是%d\n",num);
    num *= 2 + 3;
    printf("num是%d\n",num);
    num = 10;
    num++;
    printf("num是%d\n",num);
    ++num;
    printf("num是%d\n",num);
    return 0;
}
结果:
num是44
num是50
num是250
num是11
num是12

使用自增(自减)操作符编写的表达式也可以当作数字使用,前操作当作数字使用的时候是修改后的数字后操作当数字使用的时候是修改前的数字

/CSD1702/biaoc/day04 02opr.c

/*
	操作符演示
*/
#include <stdio.h>
int num2;
int main(){
    int num = 0,num1 = 0;
    char ch = 0;
    num = ch = 300;
    printf("num是%d\n",num);
    num += 6;
    printf("num是%d\n",num);
    num *= 2 + 3;
    printf("num是%d\n",num);
    num = 10;
    num++;
    printf("num是%d\n",num);
    ++num;
    printf("num是%d\n",num);
    
    num = 10;
    num1 = ++num;
    printf("num是%d,num1是%d\n",num,num1);
    num1 = num++;
    printf("num是%d,num1是%d\n",num,num1);
    
    num = 10;
    num1 = num++ + ++num;
    printf("num是%d,num1是%d\n",num,num1);
    num2 = 10;
    num1 = num2++ + ++num2;
    printf("num2是%d,num1是%d\n",num2,num1);
    return 0;
}
结果:
num是44
num是50
num是250
num是11
num是12
num是11,num1是11
num是12,num1是11
num是12,num1是22     //结果不确定
num2是11,num1是21    //结果不确定

不要在一条语句里对同一个变量多次进行自增或自减计算,因为结果不确定

STDC01_day04_04-运算符03.ts

逻辑操作符用来编写逻辑表达式
逻辑表达式的计算结果只能是布尔值

!是一个单目逻辑操作符,它可以根据一个布尔值计算出相反的布尔值
它代表的操作叫做求反

/CSD1702/biaoc/day04 03logic.c

/*
    逻辑操作符演示
*/
#include <stdio.h>
int main(){
	printf("!8是%d\n",!8);   
    return 0;
}
结果:
!8是0

双目逻辑操作符==(等于),!=(不等于),>(大于),<(小于),>=(大于等于)和<=(小于等于)

3 < 7 <5

/CSD1702/biaoc/day04 03logic.c

/*
    逻辑操作符演示
*/
#include <stdio.h>
int main(){
    printf("!8是%d\n",!8);
    printf("3 < 7 < 5是%d\n",3 < 7 < 5);
    return 0;
}
结果:
!8是0
3 < 7 < 5是1

3 < 7 先算出逻辑值1,然后1 < 5也是真

最多只包含一个双目逻辑操作符的表达式叫简单逻辑表达式,简单逻辑表达式在数学里和计算机里的结果一定一样

C语言里包含多个双目逻辑操作符的表达式必须首先拆分成多个简单逻辑表达式然后再合并

可以采用与(&&)和或(||)这两个双目逻辑操作符把两个逻辑表达式合并

只要两个逻辑表达式里有一个的结果是假则用与(&&)合并后结果就是假
只要两个逻辑表达式里有一个的结果是真则用或(||)合并后结果就是真

3 < 7 < 5改写成计算机能用的表达式 3 < 7 && 7 < 5

/CSD1702/biaoc/day04 03logic.c

/*
    逻辑操作符演示
*/
#include <stdio.h>
int main(){
    printf("!8是%d\n",!8);
    printf("3 < 7 < 5是%d\n",3 < 7 < 5);
    printf("3 < 7 && 7 < 5是%d\n",3 < 7 && 7 < 5);
    return 0;
}
结果:
!8是0
3 < 7 < 5是1
3 < 7 && 7 < 5是0

与(&&)和或(||)都具有短路特征(如果前一个逻辑表达式的结果能决定整个逻辑表达式的结果则后一个逻辑表达式不计算)

STDC01_day04_05-运算符04.ts

/CSD1702/biaoc/day04 03logic.c

/*
    逻辑操作符演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("!8是%d\n",!8);
    printf("3 < 7 < 5是%d\n",3 < 7 < 5);
    printf("3 < 7 && 7 < 5是%d\n",3 < 7 && 7 < 5);
    1 || ++num;    //短路特征
    printf("num是%d\n",num);
    0 && ++num;    //短路特征
    printf("num是%d\n",num);
    return 0;
}
结果:
!8是0
3 < 7 < 5是1
3 < 7 && 7 < 5是0
num是0
num是0

假设有三个变量gender,height和weight分别记录一个人的性别,身高和体重
0代表女人,1代表男人

男人身高减体重小于105算超重
女人身高减体重小于110算超重

要求编写逻辑表达式判断变量所代表的人是否超重

(gender && (height - weight < 105)) || (!gender &&(height - weight < 110))

见STDC01_day04_10-运算符09.ts
gender ? height - weight < 105 : height - weight < 110

STDC01_day04_06-运算符05.ts

位操作符可以直接操作二进制数位

~是一个单目位操作符
这个符号可以根据一个数字计算出另外一个数字,这两个数字所有二进制数位的内容都不一样
它所代表的操作叫按位求反

/CSD1702/biaoc/day04 04bit.c

/*
	位操作符演示	
*/
#include <stdio.h>
int main(){
    char ch = ~0x93;
    int num = ch;
    printf("num是0x%x\n",num);
    return 0;
}
结果:
num是0x6c

0x93 1001 0011
0x6c 0110 1100

双目位操作符包括按位与(&),按位或(|)和按位异或(^)
它们都可以把两个数字对应数位上的内容做计算

按位与可以把对应数位的内容做与计算
只要一个数位的内容是0则计算结果就是0

​ 3 0000 0011
& 5 0000 0101
​ 0000 0001

/CSD1702/biaoc/day04 04bit.c

/*
	位操作符演示
*/
#include <stdio.h>
int main(){
    char ch = ~0x93;
    int num = ch;
    printf("num是0x%x\n",num);
    printf("3 & 5是%d\n", 3 & 5);
    return 0;
}
结果:
num是0x6c
3 & 5是1

按位或可以把两个数字对应位数的内容做或计算
只要有一个数位的内容是1则计算结果就是1

STDC01_day04_07-运算符06.ts

​	3		0000 0011
|	5		0000 0101
​			0000 0111

/CSD1702/biaoc/day04 04bit.c

/*
	位操作符演示
*/
#include <stdio.h>
int main(){
    char ch = ~0x93;
    int num = ch;
    printf("num是0x%x\n",num);
    printf("3 & 5是%d\n", 3 & 5);
    printf("3 | 5是%d\n", 3 | 5);
    return 0;
}
结果:
num是0x6c
3 & 5是1
3 | 5是7

按位异或可以把两个数字对应数位的内容做异或计算
如果两个数位的内容一样则结果是0,否则结果是1

	3		0000 0011
^	5		0000 0101
			0000 0110

/CSD1702/biaoc/day04 04bit.c

/*
	位操作符演示
*/
#include <stdio.h>
int main(){
    char ch = ~0x93;
    int num = ch;
    printf("num是0x%x\n",num);
    printf("3 & 5是%d\n", 3 & 5);
    printf("3 | 5是%d\n", 3 | 5);
    printf("3 ^ 5是%d\n", 3 ^ 5);
    return 0;
}
结果:
num是0x6c
3 & 5是1
3 | 5是7
3 ^ 5是6

​ num % 2 奇数真偶数假
​ num & 1 二进制最后一位与1进行按位与 奇数真偶数假

移位操作可以把一个数字里的所有二进制位数内容统一向左或向右移动n个位置
>>表示向右移位操作
<<表示向左移位操作
它们都是双目位操作符
操作符左边的数字是将要进行移位操作的数字
操作符右边的数字是将要移动的位数
移位操作相当于把数字中每个二进制数位的内容换一个数位放

​    3 << 2
​	0000 0011		3
​   00000 1100		12

/CSD1702/biaoc/day04 04bit.c

/*
	位操作符演示
*/
#include <stdio.h>
int main(){
    char ch = ~0x93;
    int num = ch;
    printf("num是0x%x\n",num);
    printf("3 & 5是%d\n", 3 & 5);
    printf("3 | 5是%d\n", 3 | 5);
    printf("3 ^ 5是%d\n", 3 ^ 5);
    printf("3 << 2是%d\n", 3 << 2);
    return 0;
}
结果:
num是0x6c
3 & 5是1
3 | 5是7
3 ^ 5是6
3 << 2是12

STDC01_day04_08-运算符07.ts

左移的时候右边空出来的位置上一定填充0

/CSD1702/biaoc/day04 04bit.c

/*
	位操作符演示
*/
#include <stdio.h>
int main(){
    char ch = ~0x93;
    int num = ch;
    printf("num是0x%x\n",num);
    printf("3 & 5是%d\n", 3 & 5);
    printf("3 | 5是%d\n", 3 | 5);
    printf("3 ^ 5是%d\n", 3 ^ 5);
    printf("3 << 2是%d\n", 3 << 2);
    num = 0x7fffffff;
    printf("num >> 2是0x%x\n", num >> 2);
    return 0;
}
结果:
num是0x6c
3 & 51
3 | 57
3 ^ 56
3 << 212
num >> 20x1fffffff
​	0111    7 >> 2
​	0001	1

/CSD1702/biaoc/day04 04bit.c

/*
	位操作符演示
*/
#include <stdio.h>
int main(){
    char ch = ~0x93;
    int num = ch;
    printf("num是0x%x\n",num);
    printf("3 & 5是%d\n", 3 & 5);
    printf("3 | 5是%d\n", 3 | 5);
    printf("3 ^ 5是%d\n", 3 ^ 5);
    printf("3 << 2是%d\n", 3 << 2);
    num = 0x7fffffff;
    printf("num >> 2是0x%x\n", num >> 2);
    num = 0xbfffffff;
    printf("num >> 2是0x%x\n", num >> 2);
    printf("0xbfffffff >> 2是0x%x\n", 0xbfffffff >> 2);
    return 0;
}
结果:
num是0x6c
3 & 5是1
3 | 5是7
3 ^ 5是6
3 << 2是12
num >> 2是0x1fffffff
num >> 2是0xefffffff
0xbfffffff >> 2是0x2fffffff

解释:

1011	b >> 2           有符号类型 左边填充的是符号位  num定义为有符号类型
1110	e

1011	b >> 2           无符号类型 左边填充的是0      直接将数字移位为无符号类型
0010	2

无符号类型数字右移的时候左边空出来的位置上一定填充0有符号类型数字右移的时候左边空出来的位置上填充符号位的内容

一般情况下把数字左移n位相当于乘以2的n次方,右移n位相当于除以2的n次方
向左移32位 数变成0

位操作符不会修改任何现有存储区的内容(没有对现有存储区赋值更改存储区)

STDC01_day04_09-运算符08.ts

&也可以作为单目操作符使用,这个时候它可以用来计算一个存储区的地址 补充:取地址符
使用的时候这个符号应该写在一个存储区的前面
可以使用%p做占位符把地址数据显示在屏幕上

/CSD1702/biaoc/day04 05addr.c

/*
	地址相关操作符演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("&num是%p\n",&num);
    return 0;
}
结果:
&num是0028FF1C

我们的计算机里所有地址都是由32个二进制数位构成的

*也可以作为单目操作符使用,这个时候它可以根据一个地址找到对应的存储区 补充:取内容
使用的时候要写在一个地址前面

/CSD1702/biaoc/day04 05addr.c

/*
	地址相关操作符演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("&num是%p\n",&num);
    *(&num) = 10;    //先取变量的地址然后再取变量地址的内容
    printf("num是%d\n",num);
    return 0;
}
结果:
&num是0xbfde533c
num是10

STDC01_day04_10-运算符09.ts

三目操作符可以从两个计算规则里选择一个进行计算
三目操作符的格式如下

布尔值 ?公式一 : 公式二

如果布尔值为真就用公式一进行计算,否则用公式二进行计算

/CSD1702/biaoc/day04 06tri.c

/*
	三目操作符演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("请输入一个数字:");
    scanf("%d",&num);
    num = num >= 0 ? num : 0 - num;
    printf("绝对值是%d\n",num);
    return 0;
}
结果:
请输入一个数字:-1
绝对值是1

/CSD1702/biaoc/day04 06tri.c

/*
	三目操作符演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("请输入一个数字:");
    scanf("%d",&num);
    num = num >= 0 ? num : 0 - num;
    //num >= 0 ? num = num : num = 0 - num;  //不要在问号后面使用赋值操作符    num >= 0 ? num = num : num 满足三目操作符
    printf("绝对值是%d\n",num);
    return 0;
}

不要在问号后面使用赋值操作符

(gender && (height - weight < 105)) || (!gender && (height - weight < 110))
gender ? height - weight < 105 : height - weight < 110

练习:
编写程序从键盘得到一个0到127之间的数字,把它转换成二进制并把结果显示在屏幕上
(先显示左边的数位,后显示右边的数位)

STDC01_day04_11-运算符10.ts

/CSD1702/biaoc/day04 07bit.c

/*
	操作符练习
*/
#include <stdio.h>
int main(){
    int num = 0;
    unsigned char ch = 0x80;          //1000 0000
    printf("请输入一个数字:");
    scanf("%d",&num);
    printf("%d",(num & ch) != 0);
    ch >>= 1;
    printf("%d",(num & ch) != 0);
    ch >>= 1;
    printf("%d",(num & ch) != 0);
    ch >>= 1;
    printf("%d",(num & ch) != 0);
    ch >>= 1;
    printf("%d",(num & ch) != 0);
    ch >>= 1;
    printf("%d",(num & ch) != 0);
    ch >>= 1;
    printf("%d",(num & ch) != 0);
    ch >>= 1;
    printf("%d\n",(num & ch) != 0);
    return 0;
}
结果:
请输入一个数字:91
01011011

预习:
​ 1.类型转换
​ 2.分支(if分支和switch...case分支)
​ 3.for循环

day5: 分支语句 、 for循环 、 break和continue

STDC01_day05_01-运算符11.ts

如果一个表达式里多个数字的类型不同就必须首先转换成同一个类型然后才能计算
这个转换过程叫隐式类型转换,由计算机完成

隐式类型转换中一定把占地小的类型转换成占地大的类型

/CSD1702/biaoc/day05 01type.c

/*
	类型转换演示
*/
#include <stdio.h>
int main(){
    printf("sizeof(1 ? 1 : 0.9)是%d\n",sizeof(1 ? 1 : 0.9));
    return 0;
}
结果:
sizeof(1 ? 1 : 0.9)是8 

如果不同类型的大小一样就把整数类型转换成浮点类型把有符号类型转换成无符号类型

/CSD1702/biaoc/day05 01type.c

/*
	类型转换演示
*/
#include <stdio.h>
int main(){
    printf("sizeof(1 ? 1 : 0.9)是%d\n",sizeof(1 ? 1 : 0.9));
    printf("-7 + 3 > 0是%d\n", -7 + 3 > 0);
    printf("-7 + 3u > 0是%d\n", -7 + 3u > 0);    //隐式类型转换为无符号类型   将-7转换成无符号类型 保存在计算机内的二进制数不变
    return 0;
}
结果:
sizeof(1 ? 1 : 0.9)是8
-7 + 3 > 0是0
-7 + 3u > 0是1

-7转换成无符号类型时是一个非常大的数字,如果用%d作为占位符显示-7+3u为-4,用%u作为占位符就是一个非常大的数字,我们能看到什么内容取决我们用的占位符

C语言里可以随时给一个数字指定一个类型,这叫做强制类型转换
强制类型转换的格式如下
(char)300
强制类型转换有可能造成数据丢失

/CSD1702/biaoc/day05 01type.c

/*
	类型转换演示
*/
#include <stdio.h>
int main(){
    printf("sizeof(1 ? 1 : 0.9)是%d\n",sizeof(1 ? 1 : 0.9));
    printf("-7 + 3 > 0是%d\n", -7 + 3 > 0);
    printf("-7 + 3 > 0是%d\n", -7 + 3u > 0);
    printf("%d %d\n",300,(char)300);
    return 0;
}
结果:
sizeof(1 ? 1 : 0.9)是8
-7 + 3 > 0是0
-7 + 3 > 0是1
300 44

类型转换不会修改现有存储区的内容,计算机会分配一个新的存储区记录转换后的数字

STDC01_day05_02-分支语句01.ts

分支结构可以从几组语句选择一组执行而忽略其他组
如果程序中遇到多种可能性,每种可能性需要专门的语句处理就可以使用分支语句

if关键字可以用来编写分支
if分支里需要为每种可能性编写对应的处理语句
if分支里需要为每组语句编写配对的逻辑表达式,当某个逻辑表达式为真的时候就执行它配对的语句

if(){
}
else if(){
}
else if(){
}

有可能同时执行的语句不可以包含在一个分支里

编写if分支之前必须首先确定有多少个可能性

/CSD1702/biaoc/day05 02if.c

/*
	if分支演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("请输入一个数字:");
    scanf("%d",&num);
    if (num >= 0){
        printf("非负数\n");
    }
    else if(num < 0){
        printf("负数\n");
    }
    return 0;
}
结果:
请输入一个数字:4
非负数

请输入一个数字:-6
负数

/CSD1702/biaoc/day05 02if.c

/*
	if分支演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("请输入一个数字:");
    scanf("%d",&num);
    /*if (num >= 0){
        printf("非负数\n");
    }
    else if(num < 0){
        printf("负数\n");
    }*/
    if (num > 0){
		printf("正数\n");
	}
	else if (num < 0){
    	printf("负数\n");
	}
	else if (!num){
    	printf("零\n");
	}
	return 0;
}
结果:
请输入一个数字:6
正数

请输入一个数字:-3
负数

请输入一个数字:0
零

STDC01_day05_03-分支语句02.ts

/CSD1702/biaoc/day05 02if.c

/*
	if分支演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("请输入一个数字:");
    scanf("%d",&num);
    /*if (num >= 0){
        printf("非负数\n");
    }
    else if(num < 0){
        printf("负数\n");
    }*/
    if (num > 0){
		printf("正数\n");
	}
	else if (num < 0){
    	printf("负数\n");
	}
	else {
    	printf("零\n");
	}
	return 0;
}
结果:
请输入一个数字:5
正数

请输入一个数字:-2
负数

请输入一个数字:0
零

如果分支中一定要执行一组语句就可以省略最后一组语句的逻辑表达式和if关键字

如果if分支中多个逻辑表达式同时为真就执行其中前一个逻辑表达式对应的语句而忽略后面的逻辑表达式

/CSD1702/biaoc/day05 03if.c

/*
	if分支演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    printf("请输入一个数字:");
    scanf("%d",&num);
    if (num < 0){
        printf("负数\n");
    }
    else if (num & 1){
        printf("奇数\n");
    }
    else if (!(num & 1)){
        printf("偶数\n");
    }
    return 0;
}
结果:
请输入一个数字:-1
负数

1的二进制为 	00000000 00000000 00000000 00000001
-1的二进制为	11111111 11111111 11111111 11111110 +1
​		=	11111111 11111111 11111111 11111111

上述程序输入-1时同时满足前两个if条件(num < 0)(num & 1)

if分支里每组语句和前面的所有逻辑表达式都有关系

编写if分支的时候应该把逻辑表达式简单的写在前面

练习:
编写程序从键盘得到三个数字,找到其中最大的数字并显示在屏幕上

STDC01_day05_04-分支语句03.ts

/CSD1702/biaoc/day05 04if.c

/*
	分支练习
*/
#include <stdio.h>
int main(){
    int num = 0, num1 = 0, num2 = 0;
    printf("请输入三个数字:");
    scanf("%d%d%d",&num,&num1,&num2);
    if (num > num1 && num > num2){
        printf("最大数字是%d\n",num);
    }
    else if (num1 > num && num1 > num2){
        printf("最大数字是%d\n",num1);
    }
    else {
        printf("最大数字是%d\n",num2);
    }
    return 0;
}
结果:
请输入三个数字:34 56 72
最大数字是72

/CSD1702/biaoc/day05 04if.c

/*
	分支练习
*/
# include <stdio.h>
int main(){
    int num = 0, num1 = 0, num2 = 0;
    printf("请输入三个数字:");
    scanf("%d%d%d",&num,&num1,&num2);
    //初学者做法
    /*if (num > num1 && num > num2){
        printf("最大数字是%d\n",num);
    }
    else if (num1 > num && num1 > num2){
        printf("最大数字是%d\n",num1);
    }
    else {
        printf("最大数字是%d\n",num2);
    }*/
    //提倡的做法
    if (num > num1){
        if (num > num2){
            printf("最大数字是%d\n",num);
        }
        else {
            printf("最大数字是%d\n",num2);
        }
        
    }
    else {
        if (num1 > num2){
           printf("最大数字是%d\n",num1); 
        }
        else{
           printf("最大数字是%d\n",num2); 
        }
    }
    return 0;
}

如果一个分支里包含有限个整数,每个整数都要使用专门的语句处理就可以使用switch...case格式编写分支解决

/CSD1702/biaoc/day05 05switch.c

/*
	switch...case分支演示
*/
#include <stdio.h>
int main() {
    int season = 0;
    printf("请输入一个整数:");
    scanf("%d",&season);
    switch (season) {
    case 0:
        printf("春天\n");
        break;
    case 1:
        printf("夏天\n");
        break;
    case 2:
        printf("秋天\n");
        break;
    case 3:
        printf("冬天\n");
        break;
    default:
        printf("不认识的数字\n");        
    }
    return 0;
}

STDC01_day05_05-for循环01.ts

循环可以让一组语句反复多次执行
for关键字可以用来编写循环
for循环里可以让一个变量一次代表一组数字,然后使用一组语句处理它所代表的每个数字
这个变量叫做循环变量
采用如下结构描述循环变量的变化过程
(把开始数字赋值给循环变量;用逻辑表达式描述循环变量和结束数字的关系;循环变量每次的变化规律)

/CSD1702/biaoc/day05 06for.c

/*
	for循环演示
*/
#include <stdio.h>
int main() {
    int num = 0;
    for(num = 1;num <= 5;num++){
        printf("%d ", num);
    }
    printf("\n");
    return 0;
}
结果:
1 2 3 4 5

在编写for循环之前必须使用一组数字的变化过程描述问题

练习:
编写程序在屏幕上显示如下5行内容
每次显示一行
54321
5432
543
54
5

STDC01_day05_06-for循环02.ts

/CSD1702/biaoc/day05 07for.c

/*
	for循环练习
*/
#include <stdio.h>
int main() {
    int num = 0;
    for(num = 54321;num >= 5;num /= 10){
        printf("%d\n", num);
    }
    return 0;
}
结果:
54321
5432
543
54
5

练习:
编写程序从键盘得到两个整数,计算它们之间所有整数的和并把结果显示在屏幕上

自己练习程序

/*
	for循环练习
*/
#include <stdio.h>
int main(){
    int sum = 0;
    int num = 0,num1 = 0, i = 0;
	printf("请输入两个整数:");
    scanf("%d %d",&num,&num1);
    printf("%d和%d之间的数之和是",num,num1);
    if (num > num1){
        for(i = num1;i <= num;i++){
            sum = sum + i;
        }
    }
    else {
        for(i = num;i <= num1;i++){
            sum = sum + i;
        }
    }
    printf("%d\n",sum);
}

/CSD1702/biaoc/day05 08for.c

/*
	for循环练习
*/
# include <stdio.h>
int main(){   
    int min = 0, max = 0, num = 0, tmp = 0, sum = 0;
	printf("请输入两个整数:");
    scanf("%d %d", &min, &max);
    if (max < min){
        tmp = max;
        max = min;
        min = tmp;
    }
    for (num = min;num <= max;num++){
        sum += num;
    }
    printf("求和结果是%d\n",sum);
    return 0;
}

STDC01_day05_07-for循环03.ts

假设有如下的for循环

for (1;2;3){
	4
}

它按照以下方式分组执行
[1,2][4,3,2][4,3,2]...[4,3,2]
第一组和其他组都不同,正常情况下for循环应该在两组之间结束
如果某一组最后编号为2的逻辑表达式结果为假就立刻结束循环
如果for循环正常结束则结束后循环变量一定落在指定数字范围之外
for循环有可能不执行大括号里面的语句

for循环小括号里任何部分都可以省略
如果省略小括号中间的逻辑表达式就表示逻辑表达式结果永远为真,这种循环不能正常结束,它们叫做死循环

/CSD1702/biaoc/day05 09for.c

/*
	for循环演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    for (num = 1;;num++){
        printf("%d\n", num);
    }
    return 0;
}

小括号里最前面和最后面的部分可以是用逗号链接的多条语句

/CSD1702/biaoc/day05 09for.c

/*
	for循环演示
*/
#include <stdio.h>
int main(){
    int num = 0, num1 = 0;
    /*for (num = 1;;num++){
        printf("%d\n", num);
    }*/
    for (num = 1,num1 = 9;num <= num1;num++,num1--){
        printf("%d X %d = %d\n", num, num1,num * num1);
    }
    return 0;
}
结果:
1 X 9 = 9
2 X 8 = 16
3 X 7 = 21
4 X 6 = 24
5 X 5 = 25

STDC01_day05_08-for循环04.ts

C99规范里允许在循环的小括号里临时声明循环变量
这种循环变量只能在循环里使用,循环结束后就不能使用了

/CSD1702/biaoc/day05 09for.c

/*
	for循环演示
*/
#include <stdio.h>
int main(){
    /*int num = 0, num1 = 0;
    for (num = 1;;num++){
        printf("%d\n", num);
    }*/
    /*for (num = 1,num1 = 9;num <=num1;num++,num--){
        printf("%d X %d = %d\n", num, num1,num * num1);
    }*/
    for (int num2 = 1;num2 <= 5;num2++){
        printf("%d", num2);
    }
    printf("\n");
    //printf("num2是%d\n",num2);     错误
    return 0;
}
结果:12345

采用C99规范编译命令 gcc -std=c99 09for.c

练习:鸡兔同笼
一共40个头,100只脚
编写程序计算兔子和鸡各有多少只

/CSD1702/biaoc/day05 10for.c

/*
	鸡兔同笼
*/
#include <stdio.h>
int main(){
   	int num = 0;    //兔子数量(头的数量)
    for (num = 0;num <= 40;num++){
        if (4 * num + 2 * (40 - num) == 100) {    //腿数量和为100
            printf("兔子一共有%d只,鸡一共有%d只\n", num, 40 - num);
        }
    }
    return 0;
}
结果:
兔子一共有10只,鸡一共有30只

STDC01_day05_09-break和continue01.ts

/CSD1702/biaoc/day05 10for.c

/*
	鸡兔同笼
*/
#include <stdio.h>
int main(){
   	int num = 0;
    for (num = 0;num <= 40;num++){
        if (4 * num + 2 * (40 - num) == 100) {
            printf("兔子一共有%d只,鸡一共有%d只\n", num, 40 - num);
        }
    }
    printf("num是%d\n",num);
    return 0;
}
结果:
兔子一共有10只,鸡一共有30只
num是41    //循环正常结束,循环变量落在指定范围之外

可以在循环里使用break;语句立刻结束循环的执行
执行完break;语句后,循环里的一切语句都不再执行,包括循环变量也不再变化
如果循环采用break;语句结束则结束后循环变量一定落在数字范围之内
如果编写循环的时候无法事先计算循环的次数就可以编写死循环,然后在循环里使用break;语句结束循环

可以在循环里使用continue;语句直接跳到循环大括号的末尾,中间的语句这次循环都不执行

/CSD1702/biaoc/day05 11continue.c

/* 
	continue语句演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    for (num = 1;num <= 5;num++){
        printf("%d ",num);
       	printf("%d ",10 + num);
    }
    printf("\n");
    return 0;
}
结果:
1 11 2 12 3 13 4 14 5 15

/CSD1702/biaoc/day05 11continue.c

/* 
	continue语句演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    for (num = 1;num <= 5;num++){
        printf("%d ",num);
        continue;	//跳到循环末尾
       	printf("%d ",10 + num);
    }
    printf("\n");
    return 0;
}
结果:
1 2 3 4 5

continue;break;语句一般在分支中使用

/CSD1702/biaoc/day05 11continue.c

/* 
	continue语句演示
*/
#include <stdio.h>
int main(){
    int num = 0;
    for (num = 1;num <= 5;num++){
        printf("%d ",num);
        if (num == 3){
            continue;	//跳到循环末尾 不打印13
        }            
       	printf("%d ",10 + num);
    }
    printf("\n");
    return 0;
}
结果:
1 11 2 12 3 4 14 5 15 

练习:
编写程序从键盘得到一个0到100之间的数字,把这个数字到100之间所有和7无关的数字显示在屏幕上。

自己编写的程序

/* 
	continue语句练习
*/
#include <stdio.h>
int main(){
    int num = 0,i = 0;
    printf("请输入一个0到100之间的数字:");
    scanf("%d",&num);
    for (i = num;i <= 100;i++){
        if (i % 7 == 0 || i / 10 == 7 || i % 10 == 7){	//i % 7 == 0 表示7的倍数 
            continue;	//跳到循环末尾					//i / 10 == 7 表示70-79
        }                              					//i % 10 == 7 判断个位是不是7
       	printf("%d\n",i);
    }
    return 0;
}

/CSD1702/biaoc/day05 12for.c

/* 
	for循环练习
*/
#include <stdio.h>
int main(){
    int num = 0, min = 0;
    printf("请输入一个数字:");
    scanf("%d", &min);
    for (num = min;num <= 100;num++){
        if(!(num % 7)){	//相当于 num % 7 == 0再取反,判断num是7的倍数
            continue;	//不执行操作,跳到循环末尾
        }
        if(num % 10 ==7){//判断num是否个位是7
        	continue;
        }
        if(num >= 70 && num <= 79){	//判断在70到79之间
        	continue;       
        }
        printf("%d ",num);
    }
    return 0;
}
结果:
请输入一个数字:10
10 11 12 13 15 16 18 19 20 22 23 24 25 26 29 30 31 32 33 34 36 38 39 40 41 43 44 45 46 48 50 51 52 53 54 55 58 59 60 61 62 64 65 66 68 69 80 81 82 83 85 86 88 89 90 92 93 94 95 96 99 100 

预习:
​ 1.for循环
​ 2.多重循环
​ 3.while循环和do...while循环
​ 4.缓冲区管理
​ 5.数组

猜你喜欢

转载自blog.csdn.net/u013673437/article/details/88061265
今日推荐