2,笔记内容
(1)基本概念
计算机构型:
冯诺依曼型 程序存储于 存储器中 通过不断执行存储器中的指令
计算基本组成:
1. 输入 键盘鼠标 麦克风 传感器
输出 屏幕 喇叭 打印机
CPU: GPU(图形处理器) APU(AI处理器) FPU(浮点运算单元)
2. 运算器 ALU 运算单元 完成 运算操作
3. 控制器 协调各个部件工作 从存储读取指令
4. 存储器 存储数据
金字塔模型:
寄存器 在CPU 容量很小 个 速度最快
高速缓存(cach) 容量小 M
内存(RAM): 随机存储器 内存条 容量较大 G
掉电数据丢失
外设存储器: 硬盘 容量大 T 掉电不丢失 速度慢
机械硬盘 价格便宜 数据稳定
固态硬盘
什么是程序?
完成一件事的 步骤和方法
写简历 ---- 投简历 ---- 面试 ----- 入职
计算机程序?
通过计算机指令 让计算机完成 某件事情的 步骤和方法
数字计算机 只能识别 0 1
计算机指令: 即对 特定操作的二进制编码
什么叫编程?
使用 计算机语言 将要执行的动作和步骤 告知计算机
低级编程语言: 汇编语言 汇编指令
编程语言: 用于人与 计算机 之间交流的 语言
高级编程语言: 更贴近与人 的 思维方式或逻辑 可移植性强
C语言 C++ : 编译型语言
Python : 解释型语言
Java :
....
编译型语言: 即 将整个程序 需要预先 编程 成 可执行的二进制指令 才能被计算机执行
运行效率高, 一次编译 可以一直使用
解释型语言: 即 将程序 逐行解释 为 指定的 二进制指令 交由计算机执行
即写程序 和 运行 可以同步进行 节省编译时间
每次程序的运行 都需要同步解释, 运行效率不高
编程语言的组成: C语言
1. 词法符号
关键字: 由编译器预先 定义的有特殊功能的单词短语
运算符: 表示某种运算符符号 + - * /
标识符: 由编程者 自己定义的 名字
分隔符: 用于排版,方便阅读,美观, 但对编译没有任何影响
标点符号:一些有特定位置 特定情况使用的标点符号,参与编译的
严格按照规范使用 ;
2. 结构语法 只能实现在函数中
顺序结构
分支结构
循环结构
C语言编译器:
一个软件, 可以将C源码,编译为 可执行机器码
编译标准:
C98 C99标准
C库: 由编译器自带的一些 有前辈大师编写 一些常用的功能函数
Ubuntu16.04 虚拟机的使用:
图形界面 与 Windows 类似
终端界面 字符界面
终端: 一个链接计算机的 命令窗口
ctrl + alt + t 打开一个新终端窗口
ctrl +shift + t 在同一个窗口中打开新终端
在一个窗口中切换终端
alt + 1 切换到窗口1
alt + 2 切换到窗口2
....
Linux系统: 一个开源 免费的 多任务 多用户的 操作系统
可移植性好 可以裁剪
GNU组织, GPL协议 开源共享协议
Android 是一个Linux的应用程序
桌面右键 新建终端
终端提示符 表示可以输入命令
xwq@xwq-pc:~$
用户名@主机名: ~ 当前工作目录 ~ 家目录 $ 表示普通用户 # 管理员 root
(2)linux系统基本命令
cd 命令 进入目录
cd 目录名 进入该目录
cd .. 返回上一级目录
删除文件和目录
rm 文件或目录名 -rf
递归删除文件或目录中的所有内容
创建目录
mkdir 目录名
mkdir c基础
删除目录
rmdir 空目录名
创建一个普通文件
touch 普通文件名
编辑文本文件
1. 使用图形界面编辑
gedit 文件名
使用图形界面记事本编写C代码
2. vim 字符界面 文本编辑器 来编写C代码
vim 文件名 打开文本文件 若该文件不存在 将会自动创建
vim 命令模式: 默认进入vim 就是命令模式
该模式下 键盘输入的都认为是命令
dd 剪切一行 光标所在行
5dd 剪切5行 光标所在行以及后边4行
p 粘贴 在光标下一行 粘贴
yy 复制光标所在行
5yy 复制光标所在行以及后边4行
x 删除光标所在字符
u 撤回上一次操作
进入 插入模式
命令模式下 输入 i o a
i 进入插入模式 从光标位置前开始插入
o 进入插入模式 从光标下新建一行并从该行开头插入
a 进入插入模式 从光标位置后开始插入
退出插入模式 到 命令模式
esc
进入底行模式 该模式下 主要是操作文件 保存 退出 等
:wq 保存退出
:q! 强制退出 不保存
:w 仅保存
:wqa 保存并退出所有文件
多文件编辑 vim 1.c hello.c -o -o水平切分窗口 -O 垂直切分窗口
(3)c基础知识
第一个C代码:
vim hello.c
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
编译C源码文件
gcc hello.c
默认生成一个 a.out文件 就是该工程的可执行文件
运行可执行文件
./a.out
C语言对标点符号 要求严格 区分大小写中英文符号等
gcc 编译时 重新命名 输出 可执行文件的名字
gcc hello.c -o hello
Linux重命名文件
mv 命令 可以移动或重命名文件
mv hello.c 2.c
修改hello.c 为 2.c
C语言关键字:32个
1.类型相关的
基本数据类型: char double float int long short signed unsighed void
构造数据类型: struct union enum
2.存储相关
auto const extern register static
3.结构相关
break case continue default do while if else
for goto return switch
4.特殊功能
sizeof typedef volatile
计算机中 数据的表示
数值数据(基本数据类型) 10 3.5 -5 即一个数
非数值型数据 自然语言 "hello world" "你好" "123" "13727045125"
ASCII 英文字符 及 符号 和 控制命令 的 编码
C语言中 使用"" 引用其他的数据 称字符串
图片 语音 ....
数据存储与表示:
计算机只能处理与存储 0和1类型数据 最小单位 bit 0-1 内存最小单位是字节 1Byte=8bit
数值数据 二进制 与 十进制
进制的表示: 0b 二进制 默认10进制 8进制 0o 16进制 0x
123 十进制数 逢十进一
数码 0 1 2 3 4 5 6 7 8 9
1 * 10 ^ 2 + 2 * 10 ^ 1 + 3 * 10 ^ 0 = 123
0b1011 二进制 逢二进一
数码 0 1
0b1011 = 1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 1 *2^0
= 11 十进制
0
1
10
11
100
...
10进制转 2进制 算法
123 余数 == 0b111 1011 == 0x7b
/2 61 --- 1 二进制低位
/2 30 --- 1
/2 15 --- 0
/2 7 --- 1
/2 3 --- 1
/2 1 --- 1
/2 0 --- 1 二进制高位
16进制 逢16进一 半斤八两
数码 0-9 A(10) B(11) C(12) D(13) E(14) F(15)
123 0x7b
/16 7 ---- 11
/16 0 ---- 7
进制 方便人 阅读 编写 程序
8进制
面试题: 有100瓶药水 有一瓶毒药 药效发作时间需要1小时
现有 8只 小白鼠 如何操作 可以在 最短的时间内找到这瓶毒药
假设 除毒药发作时间外 都不需要时间
C语言中,对数 设计类型:
数据类型: 即 对 不同类型的数 的 表示 和 存储
整数类型 精确类型
char 字符型 8bit 1字节 存储这个数 0-255 共256个数
short 半字类型 16bit 2字节 0-2^16-1 = 65535
int 整型 32bit 4字节 0-2^32-1 = 4,294,967,295
long 长整型 64bit 8字节 0-2^64-1 =
int 与 long 存储大小
一些8位单片机 51 int 2字节 long 4字节
一些32位单片机 stm32 或 LinuxC int 4字节 long 8字节
signed 有符号类型 不写默认是有符号类型
unsigned 无符号类型
signed char 有符号字符型 -128 ~ + 127
unsighed char 无符号字符型
有符号与无符号的区别
负数如何表示 -2 -10 -1
有符号数 最高bit 作为符号位 0 正数 1 负数
signed char -128 ~ 0 ~ +127
补码形式 存储有符号类型
LinuxC中:
不写 signed 默认 都是有符号 gcc
单片机C中 arm gcc
char 不写 默认无符号类型
除char类型 外 其他不写signed 默认是有符号类型
最高位 为 符号位 其余位 存储值 若值是负数 补码
负数值 = 补码取反 +1
强类型语言:
C语言: 任何变量或存储空间 必要先定义(给定类型 ) 然后才能使用
且 使用过程中 类型不不能更改
小数: 2.5 0.71231 0.0000000000000012 21873541623584713527412348234.12341341
非精确类型: 数据 有 有效位数 超过有效位数的数据丢弃
浮点类型存储与表示:
使用幂指数方式存储小数
0.25 * 10^-1
0.71231 * 10^0
0.12 * 10^-14
0.21873541 * 10^29
浮点数存储:
flaot 单精度浮点型 4字节存储 有效十进制位数 约6位
最高bit 符号位 8bit 幂指数位 23 位有效位
double 双精度浮点型 8字节存储 有效十进制位数 约15位
最高bit 符号位 11bit 幂指数位 52 位有效位
逻辑上:
布尔类型 bool 真 假 有一些运算 或操作 其结果是布尔类型 关系运行 逻辑运算
C语言中 真 非0 为真 0假
void 类型 空类型
(4)常量
C语言中的常量
常量: 程序运行过程中 始终不变的量
整型常量: 5 10 -5 整数值 8
浮点常量: 2.5 -3.7
指数常量: 3.0e-26 => 3*10^-26
字符常量: 单个英文字符 'a' '8' === 56 ASCII
字符串常量: 多个字符放在一起 "hello world"
在内存中 存储的是 字符的 编码 连续存储
标识常量(宏定义): 本质是给 常量 定义一个字符串形式的 别名
#define 宏名 值
#define PI 3.14
#define WATER 3.0e-26
字符在计算机中的存续:
将非数值类型数据 进行 编码 转换为 数值类型 存储;
英文字符 与 数字 符号 ASCII 编码标准
编码
0-31 表示一些 文本动作
32-126 有对应字符
解码 字库
65 ====> 'A'
中文编码 GBK 编码 2字节表示一个 中文
utf-8 编码 3字节表示 一个中文
将Windows中的文件 放到 Ubuntu中 :
通过共享文件
Linux 的 cp命令
cp 文件名 目标路径
(5)变量
变量: 程序运行过程中 可能改变的量
其本质 即 给一个 内存空间 命名 通过该名字访问内存
C语言中 的 变量 1. 先定义在使用 2. 定义时给定类型 一旦定义完成 其类型将不能改变
示例 变量的定义:
存储类型 数据类型 变量名;
auto int a; // 即表示 声明一段4字节内存空间 命名为 a
若省略存储类型 即 auto 类型
存储类型: 决定了 变量存储的位置
C语言内存结构:
常量或代码: a.out
1.代码段: 存储代码 即编译的二进制指令 只读
2.常量区: 存储程序中的 常量 "" 的部分 常量字符串 只读
可以使用 const 关键字 修饰全局变量 将该变量的存储位置 变更为常量区
变量:
3.静态区: 可读可写 只能被初始化 一次 在程序开始运行时
该区域变量 将从程序开始 一直存在到程序结束
未初始化的 静态区变量 都默认初始化为0
4.堆区: 有程序员 在程序运行时 可以手动 动态(长度不确定)申请或释放的 内存
5.栈区: 有程序运行时 自动(函数形参或局部变量) 申请或释放的 内存
未初始化的栈区堆区变量 其初始值不确定
由系统维护的数据:
6.系统区: LinuxC有, 存储操作系统对于该进程的 一些数据
进程控制块,内存占用情况, 环境变量等 只读
全局变量: 变量定义的位置 在函数外(不在任何函数内 {}) 可以在整个程序中使用
局部变量: 变量定义的位置 在函数内( 在 {} 中定义的) 只能在{}内部使用
auto 修饰全局变量 该变量存储与 静态区
auto 修饰局部变量 该变量存储与 栈区
const 修饰全局变量 该变量存储与 常量区
static 修饰局部变量 该变量存储与 静态区
只能在{}内使用 只能被初始化 一次 在程序开始运行时
static 修饰全局变量 该变量存储与 静态区
只能在当前C文件中使用 只能被初始化 一次 在程序开始运行时
多用于防止全局变量重名 导致的问题
static 修饰函数 该函数只能在 本文件内使用
变量赋值 变量名 = 值; 即 向内存中 写入值
变量初始化 即 定义时 赋值 ;
extern 修饰全局变量 表示外部 引入 存储类型 不开辟新的内存 空间
是一种声明
extern 函数 表示引入外部文件实现的 函数
register 寄存器类型 声明 表示变量 尽量使用寄存器存储
通常用于修饰 在一段代码中 使用极其频繁的 量
该存储类型的变量 不能取地址 &
变量名: 由编程者 自己定义的名字
程序中 变量名 函数名 宏名 都是 标识符
命名规范:
1. 只能由 字母 数字 下划线 组成 区分大小写
2. 不能由数字开头
3. 不能与 关键字重名 32个
int 张3; int 7a; int char; 不行
int _abc; int printf; 可以
库标识符: 库中 有对于该标识的定义
系统标识符: 由编译定义了的 include
(6)数据类型
数据类型的转换: 将类型不匹配 的数据 转换为 对应匹配类型的数据格式
隐式类型转换: 有编译器 自动完成 一些默认转换模式
强制类型转换: 编程者 手动进行的 强制性的类型 转换
变量 或 值 前 使用(目标类型)
类型的转换过程:
float ---> int 舍弃小数 取整操作
int ---> float 整型(精确类型) 小数(非精确类型) 精度会丢失
int ---> char 溢出部分舍弃 宽存储空间 转换为 小存储空间
int ---> short
小存储空间 转换为 宽存储空间 不影响
整型与浮点型 参与运算时 隐式类型转换 会统一转换为浮点型计算
有符号数 无符号数 强制类型转换时 存储内容 完全没有改变 但影响计算
C语言中标准输入与输出:
标准输入: 程序终端 输入的内容
标准输出: 程序输出 到终端显示
输出: 使用man 函数名 查询该函数
putc(); 输出一个字符 'a'
putchar(); 与putc一样
puts(); 输出一个字符串 "hello world"
格式化输出函数
printf();
#include <stdio.h>
int printf(const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
sprintf/snprintf 即格式化后 输出到 指定内存容器str中
返回值: 成功 返回 格式化后输出的字符个数
... 变长参数个数
使用: format 格式控制字符串 "a=%d\n",a 其中 a=\n 原样输出
%d 格式占位控制符
%d 输出整型有符号数 以10进制方式显示
%x 输出整型无符号数 以16进制方式显示
%u 输出整型无符号数 以10进制方式显示
%c 输出一个 字符型数 以字符方式显示
%s 输出一个字符串 以\0 作为结束符
%f 输出一个浮点类型 以10进制方式
%% 输出%本身
附加格式说明符(修饰符):
%8d 输出整型有符号数 以10进制方式显示
在数据值宽度低于8个字符位置时 填充空格维持8个字符位置
-8 向左对齐
8 默认右对齐
%.2f 输出一个浮点类型 以10进制方式 保留2位小数 四舍五入
%ld 输出整型有符号数 宽度为8字节long 以10进制方式显示
%lf 输出 double 类型的浮点数
(7)printf和scanf
标准输入:
#include <stdio.h>
int fgetc(FILE *stream); //得到一个字符
int getc(FILE *stream); //得到一个字符
int getchar(void); //得到一个字符
char *fgets(char *s, int size, FILE *stream); //得到一行输入
s: 存放输入字符串的容器 char buf[20];
size: 容器的大小 单位字节
stream: stdin
scanf: 格式化输入
int scanf(const char *format, ...);
int sscanf(const char *str, const char *format, ...);
sscanf 从str内存中 按格式提取
格式控制字符串: 非常类似于printf
%d 表示 输入提取为一个整型数
%f 表示 输入提取为一个小数数
%4d 表示 输入提取为一个整型数 宽度为4个数字
%4c 表示 输入提取4个字符 组成字符串
%s 输入一个字符串 默认以空格 或 回车 或 制表符(tabl)
返回值 表示成功的提取项的个数
高级用法:
输入身份证号码 510502202205050016 取出 生日
printf("请输入你的身份证号码:");
scanf("%*6d%4d%2d%2d%*5c",&y,&m,&d);
scanf 处理输入字符串时 会存在 输入残留 通常会导致 残留到下一次输入内容
处理残留:
%*c 将后续所有字符都 取出丢弃
%*6d 取出6个数字 丢弃
%*2c 取出2个字符 丢弃
方法2 scanf结束后 使用 fgets 将后续残留的读取出来
%s 读取一个字符串 以空格,回车,制表符等默认作为分隔
(8)逻辑运算
运算符: 代指某种操作的 符号
表达式: 由 运算符 与 数据 按某种顺序 组合而成的 可以计算的一个 式子
C语言中 可以支持的运算符有:
1.算数运算符: +加 -减 *乘 /除 %求余 求模
/除 5 / 3 == 1 整数除法是求商 浮点数除法 结果为浮点数
%求余 必须是整数 5 % 3 == 2
其他数学运算 没有对应运算符 可以通过math库 实现
双目运算: 需要两个数参与的运算符
2.逻辑运算: 真 与 假的 运算
符号
逻辑与 && 双目运算 真 && 真 结果为真 一假得假
逻辑或 || 双目运算 假 || 假 结果为假 一真得真
逻辑非 ! 单目运算 !真 == 假
非0 为真 0假
5 || 0 结果 真 1
5 && 0 结果 假 0
!0.5
3.关系运算 大小比较 结果 真或假
> < == != >= <=
4.位运算 计算机中特有的运算 所有运算目标 均针对二进制而言
按位 & 将二进制中的每一位进行与操作 与0得0 与1不变
按位 | 将二进制中的每一位进行或操作 或1得1 或0不变
按位取反 ~ 单目运算
按位异或 ^ 相同为0 不同为1
移位运算
逻辑左移 << 高位移出丢弃 低位补0
算数右移 >> 低位移出对齐 无符号数 高位补0 有符号数 高位补符号位
a = 1100 0110 = 0xc6
b = 1111 0001 = 0xf1
a & b
= 1100 0000
a | b
= 1111 0111
~a
= 0011 1001
a ^ b
= 0011 0111
a<<1
= 1000 1100
a>>1
无数数a = 0110 0011 == 0x63
有符号数 = 1110 0011 == -29
作用: 多用于底层编程
示例: 有一个数a 希望 a的 [6:4] 设置为 0 其他位不变
a = a & 1000 1111;
= a & ~ 0111 0000;
= a & ~( 7 << 4);
有一个数a 希望 a的 [m:n] 设置为 0 其他位不变
a = a & ~( x << n); x = 2的(m-n+1)次方-1
有一个数a 希望 a的 [6:4] 设置为 1 其他位不变
a = a | 0111 0000;
= a | (7<<4);
有一个数a 希望 a的 [m:n] 设置为 1 其他位不变
a = a | (x << n); x = 2的(m-n+1)次方-1
a = **## ##** 将a的 [5:2] 设置为 y = 1100 = 12
a1= **11 00**
a1 = ( a & ~( 0xf << 2) ) | 12 << 2;
有一个数a 希望 a的 [m:n] 设置为值 y 其他位不变
a = (a & ~(x << n)) | (y << n); x = 2的(m-n+1)次方-1
交互a,b的值
中间变量法:
int c = a;
a = b; b = c;
加法:
a = a + b;
b = a - b;
a = a - b;
亦或法 5.赋值运算的复合运算 少用
a = a ^ b; ===> a ^= b;
b = b ^ a; ===> b ^= a;
a = a ^ b; ===> a ^= b;
a = a + b; ===> a += b;
a = a - b; a -= b;
a = b - a; ===> 不能
写一个程序 打印一个数 a的 最低4个bit的值 以二进制方式输出
a = 1100 x110
(a >> 3) & 1;
== (1100 x) & 0000 0001;
== 0000 000x;
a = b;
a = 10;
a = a + b + c;
a += b + c; ===> a = a + (b + c);
a = a * b + c;
a *= b + c; ===> a = a * (b + c);
选择运算 三目运算符:
a ? b : c;
逻辑: 若a 为真 则 执行 b; 表达式的值 为 b
若a 为假 则 执行 c; 表达式的值 为 c
示例: a = 3, b=10;
x = a > b ? a : b; 将ab中最大的赋值给x
计算机算法:
x = 0 ? a : b ;
x = b;
x
表达式的值 5;
逗号运算符,
表达式1, 表达式2, ... 表达式n;
运算逻辑, 每个表达式都执行一下, 整个表达式的值 为 表达式n 的值
a = 5, b = 10;
z = (x+=5, y = x+0.2);
&变量名 取地址符 得到变量的内存首地址 只能对变量或有内存空间的量使用
sizeof运算符: sizeof(变量名或类型名); 用于计算变量或类型 占用的内存空间大小 单位字节
自增自减运算符 ++ -- 单目运算
前缀++ 运算符 ++a; 先+ a=a+1 后用
后缀++ 运算符 a++; 先用 后+ a=a+1 指a++表达式结束
前缀-- 运算符 --a; 先- a=a-1 后用
后缀-- 运算符 a--; 先用 后- a=a-1
++a++; 不行 ++( a++) 先用 ++ 5 然后 a=a+1 存在对常量赋值
int a =5;
a < a++; 结果为 假
a >= a--; 假
a >= ++a; 真
a > a++; 结果为真 ===> a > 5; a=a+1;
表达式: 运算符 优先级
int a; -a; -a - a; -(a-a);
优先级问题:
1. 优先级提升运算符 ()
2. 单目运算符 优先级高 ++ -- & + - ! ~
3. 算数运算符 高于 移位运算 高于 关系运算 高于 位运算 高于 逻辑运算
4. 吊车尾 3兄弟 三目运算 赋值运算 逗号运算符
示例:
int x=1, y=0, z=0;
x>0 && ! (y==3) || z>5
== 1 && ! (y==3) || z>5
== 1 && ! (0) || z>5
== 1 && 1 || z>5
== 1 || z>5
== 1 || 0
== 1
根据情况 设计表达式
字符变量a 判断 是否 为 英文字母 ASCII
字符变量a 介于 'a' ~ 'z' 或 'A' ~ 'Z'
表达式 为真 是英文字母 为假 不是英文字母
数学表达式 'a' <= a <= 'z' 或 'A' <= a <= 'Z'
C语言表达式 ('a' <= a && a <= 'z') || ('A' <= a && a <= 'Z') == 0
练习题:
输入一个 年份, 判断是否为闰年? 输出 0或1
1. 能被4整除 不能被100 整除
2. 能被400整除
(y % 4 == 0 && y % 100 != 0) || y % 400 == 0
作业:
1. 求下列表达式的值 int a=0,b=1,c=2;
!(a+1>0) && b==0 || c>0
a<0 || b==0 && c>0
a += b==c, b=a+2, c=a+b+c >0 ;
a++ < b-- && (a = 5); 求该表达式的值 以及 表达式结束后 ab的值
int b =1;
1 && b==2 && (b=2)
== 1 && b==2 && 2
== 1 && 1 && 2
== 1
C语言 采用此种算法:
1 && b==2 && (b=2)
== 1 && 0 && 2
== 0 && 1
== 0
2. 输入一个字符 判断是否为数字字符?
3. 输入一个数, 判断是否为 水仙花数?
水仙花数: 一个3位数 其各个位数的 立方和 等于其本身
给定一个 n位数num 求其中m位的值 m<=n
y = num / x %10; 其中x = 10^(m-1);
m
1个 = num / 1 % 10;
2十位 = num / 10 % 10;
3百位 = num / 100 % 10;
4千位 = num / 1000 % 10;
.....
C语言中的结构性语句:
1.顺序结构 从上到下依次执行
2.分支结构 需要根据条件 选择性执行某些代码或跳过某些代码
3.循环结构 根据条件 对某些代码 重复执行
分支结构:
二分支:
if( 条件表达式 )
{
语句块1; //当 条件表达式 的值为 真 时 语句块1执行
}
else
{
语句块2; //当 条件表达式 的值为 假 时 语句块2执行
}
格式简化或变种:
1. 语句块 只有一行C代码 即只有一个; 结束
代码块的 {} 可以省略不写
2. else 部分 没有代码 else {} 都可以省略
练习: 输入你的成绩 输出 及格 60 不及格
练习2: 输入你的成绩 输出 优90良80中60差
if嵌套: 即 if的代码块中包含 if结构
多分支:
结构:
switch( 整型表达式 )
{
case 常量整型表达式1:
语句块1;
break;
case 常量整型表达式2: 语句块2; break;
.....
default: 语句块n;
}
整型表达式: 表达式的值 是一个整数 可以有变量 a / 10;
常量整型表达式: 表达式的值 是一个整数 不能有变量 5+3;
运算逻辑:
计算 整型表达式 的值, 依次 从上到下 与 case 中的
常量整型表达式 的值 比较 ==
若相等, 则 执行 对应case 后的 语句块,
若 遇到break关键字 退出switch结构
若 没有break关键字 继续向下执行 后续case中的语句块
若不相等 则 继续向下比较 其他case中的值
default 语句块 在 没有命中 case中的值时
执行该语句块 若一直没有break关键字,也会执行到default 语句块
若不需要 default也可以省略
使用注意: 1.switch结构只对整型结构有效
2. 不能对变量进行case
3. case中的值不能存在相等的
(9)循环结构:
通常在程序中 需要反复执行某些动作, 则需要循环
即在某些情况下,程序会跳转到前面去继续执行代码
while 循环
结构:
while( 条件表达式 )
{
循环语句块;
}
执行逻辑:
1.先判断 条件表达式的 真假
若真: 执行一次循环语句块; 再回到动作1
若假: 退出循环 即循环结束了
do while循环
结构:
do{
循环语句块;
}while( 条件表达式 );
执行逻辑:
1. 先执行一次 循环语句块;
2. 再 判断 条件表达式的 真假
若真: 执行一次循环语句块; 再回到动作2
若假: 退出循环 即循环结束了
示例: 求 1+2+3+4+.... 100=的和
存在循环 sum += i++;
退出条件 i <= 100
练习:
1. 使用循环 打印出 10个*号
**********
for循环
结构:
for( 循环初始化语句 ; 循环条件表达式 ; 递进表达式 )
{
循环体;
}
执行逻辑:
1. 先执行一次 循环初始化语句
2. 判断 循环条件表达式 的真假
若真 执行 循环体一次; 在执行一次递进表达式; 回到 动作2
若假 退出 循环
递进表达式: 即使continue提前结束了本次循环,下一次循环开始前 递进表达式 也要执行
缩略写法:
若 循环初始化语句 没有 可以不写
若 循环条件表达式 不写 表示一直为真
若 递进表达式 不需要 也可以省略不写
死循环:
for(;;)
{}
while(1)
{}
循环控制关键字:
break; 提前跳出循环 不执行循环了 对于嵌套循环 只能跳出本循环
continue; 继续 提前结束 本次循环 重新开始下一次循环
goto 程序跳转关键字 只能在同一个函数中进行跳转
goto示例:
银行转账:
A ---> B
1. A -= 100; 若 1 失败 goto end;
2. B += 100; 若 2 失败 goto err;
printf("操作成功");
return 0;
err: // 操作回滚
A += 100;
end:
printf("操作失败!");
(10)数组 与 字符数组
构造数据类型: 有程序员设计的数据类型 基于基本数据类型的组合
数组: 将多个 相同类型的 数据 连续,有序存放 构成的数据类型 称数组
数组的元素: 即 数组中的每一个数据
数组定义:
存储类型 元素数据类型 数组名[元素个数];
示例: 存储5个整型 元素的数组
int arr[5];
数组的初始化: 定义数组时给定 初始值
int arr[5] = {初始化表};
int arr[5] = {1,2,3,4,5};
int arr[5] = {1,0,2}; //初始化表 没有包含全部元素, 剩余元素默认赋值为0
int arr[] = {1,2,3,4}; //定义数组时, 没有给定元素个数,但有初始化表
//则 数组的个数将由 初始化表中元素个数决定
int arr[]; // 不能这样定义 , 编译器无法确定你元素的个数
int arr[5] = {0}; //将数组元素全部初始化为0
int arr[5];
数组定义时 元素个数 必须预先已知和确定
即 定义数组时 其元素个数不能是变量
即 程序运行起来前, 数组元素个数应该已经确定
数组的使用:
元素访问: 读 写 数组中的元素
使用 [] 元素访问运算符
示例:
数组名[元素下标];
元素下标: 数组中的元素 从0开始 自左向右依次编号
//元素下标 可以是整型表达式
数组的遍历: 即 将数组中的 每个元素都访问一次
for(int i=0;i < sizeof(arr)/sizeof(arr[0]) ; i++)
for(int i = sizeof(arr)/sizeof(arr[0]) -1; i >= 0; i--)
除初始化外, 数组不能 通过元素列表方式赋值
arr = {1,2,3,4,5}; // 不行 C语言 不支持
数组名:
1. 代指这个数组本身 数组名[下标]; sizeof(arr);
2. 代指这片内存空间的 首地址 printf("%p",arr); //arr == &arr[0]
数组的内存模型:
数组占用空间 为 元素个数 * 每个元素的长度
&arr[0]; 该表达式 表示 取 数组arr中 0号元素的 地址
字符串: 本质也是一个数组 char 类型的数组
char buf[20];
fgtes(buf, sizeof(buf), stdin);
"hello" 常量 常量区
//定义一个字符数组 初始化为 hello
char buf[20] = "hello";
buf = "world"; // 不能 数组不能一次赋值多个元素
常量字符 "hello"
代指 1. 这个字符串本身 char buf[20] = "hello";
2. 代指 常量字符串 在常量区的地址
字符串的长度??
从字符串开始 到结束'\0' 值 0 中间有多少个字符
char *strcpy(char *dest, const char *src);
将字符串 src 拷贝一份到 dest 空间中
char *strncpy(char *dest, const char *src, size_t n);
将字符串 src 拷贝一份到 dest 空间中 n 表示需要拷贝的字符个数
3.写一个程序 判断输入的 密码 是否正确 假设正确密码为 "123456"
#include <string.h>
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
比较两个字符串 s1 和 s2 相等 返回 0 != 0 不相等
(11)函数:
完成特点功能的 代码块的集合
函数 输入和 输出:
输入: 终端输入 参数输入 硬件输入
可以没有输入 sleep(); delay(); 延时1us
输出: 终端输出 返回值输出 硬件输出 其他的逻辑输出
任何函数都有输出
函数的意义: 1. 对功能代码 的 封装 方便于多文件开发
2. 提高代码的 复用性
1. 定义函数
返回值类型 函数名(参数列表)
{
函数体;
}
返回值类型: 一个函数 可以有返回值 也可以没有 void修饰
int float char 返回值可以在 4或8字节
通常 返回值 1.表示函数执行成功或不成功的标志
2.返回一些 简单的结果
函数名: 标识符 由编程者自己定义 通常根据其功能命名
"123" == int 123; atoi
(参数列表) : 用于调用函数时 传递给函数的 一些参数 也可以没有参数 void修饰 或 不写
() : 可能有参数 但我用不到
(void) : 肯定没有参数
一个函数的 参数 可能不止一个 多个参数用,逗号 隔开
函数体: 该函数功能实现的 逻辑代码
函数需要调用才能 得以执行,, 什么时候调用 由调用者决定
函数名(实参列表); //若被调用的函数不需要参数 就 不写
实参列表 应该与 形参列表 一一对应 不能多也不能少 参数类型要一致
函数原型: 除了函数体 外 的部分 称函数原型
函数声明: 即在 函数调用前 声明一下该函数 将该函数的原型 写到调用前
函数的调用以及栈空间使用:
如图所示
函数地址传参 C高级