C语言基础篇

C语言基础篇
Zero02C语言
C语言的特点及入门
代码级别的跨平台:由于标准的存在,使得几乎同样的C代码可用于多种操作系统,如Windows,Dos,Unix等等,也适用于多种机型。
由于C语言允许直接访问物理地址,可以直接对硬件进行操作,因此它即具有高级语言的功能,又具有低级语言的许多功能,C语言可以用来写系统软件(比如操作系统,数据库,杀毒软件,防火墙,驱动,服务器)
C语言是一个有结构化的程序设计,具有变量作用域(variable scope)以及递归功能的过程式语言
C语言传递参数可以是值传递(pass by value)传递的是值,也可以传递指针(a pointer passed by value)传递的是地址。
C语言中,没有对象,不同的变量类型可以用结构体(struct)组合在一起,不是面向对象的。
预编译处理(preprocessor),生成目标代码质量高,程序执行效率高
为什么主函数定义为int型
在C99标准未发布前,一般把main函数定义为void,即无返回值类型,c99标准发布后,里面明确规定定义main时要定义成int型,原因是因为main函数是系统调用的,在main函数运行结束后,要返回一个值给操作系统,以此验证main函数是否执行正常,如果main返回值为0说明正常结束,否则说明程序运行出错,需要调用一些错误处理
(如内存分配失败,资源申请失败等)。
在C89 中,main( ) 是可以接受的的经典巨著(C程序设计语言第二版)用的就是void main( );不过在最新的C99 标准中,只有以下两种定义方式是正确的:
int main( void )
*int main( int argc, char argv[] )
如果不需要从命令行中获取参数,请用int main(void);否则请用int main( int argc, char *argv[] )
main函数的返回值类型必须是int,这样返回值才能传递给程序的调用者(如操作系统)
如果main函数的最后没有写return语句的话,C99规定编译器要自动在生成的目标文件中(如exe文件)加入return 0;,表示程序正常退出不过,我还是建议大家最好在main函数的最后加上return语句,虽然没有这个必要,但这是一个好的习惯注意,vc6不会在目标文件中加入return 0;,大概是因为vc6是98年的产品,所以才不支持这个特性现在明白我为什么建议你最好加上return语句了吧!
格式化符号
1 | %a,%A 读入一个浮点值(仅C99有效) |
第一个C语言程序
1 |
|
C程序运行机制
1.编辑:编写我们的c文件,就是源代码。
2.编译:将c程序翻译成目标文件(.obj)//在计算机底层执行
3.链接:将目标文件.obj + 库文件 生成可执行文件(.exe)//在计算机底层执行
4.运行:执行.exe文件,得到运行结果
源程序(source code)→预处理器(preprocessor)→编译器(compiler)→汇编程序(assembler)→目标程序(object code)→连接器(链接器,Linker)→可执行程序(executables)
C语言编译过程详解
编译,链接和运行详解
什么是编译
有了C源文件,通过编译器将其编译成obj文件(目标文件)
如果程序没有错误,没有任何提示,但在Debug目录下会出现一个Hello.obj文件,该文件称为目标文件。
什么是链接
有了目标文件(.obj文件),通过链表程序将其和运行需要的c库文件链接成exe文件(可执行文件)
如果程序没有错误,没有任何提示,但在Debug目录下会出现一个Hello.exe文件,该文件称为可执行文件。
为什么需要链接库文件呢?因为我们的c程序中会使用c程序库的内容,比如<stdio.h> <stdlib.h> 中的函数printf() system()等等,这些函数不是程序员自己写的,而是c程序库中提供的,因此需要链接
你会发现链接后,生成的.exe文件,比obj大了很多。
什么是运行
有了可执行的exe文件,也称为可执行程序(二进制文件)
在控制台下可以直接运行exe文件
C程序开发注意事项
对修改后的hello.c源文件需要重新编译链接,生成新的exe文件后,再执行,才能生效。
C程序的主题结构说明
1 | #include... |
C程序源文件以“c”为拓展名。
C程序的执行入口时main()函数
C语言严格区分大小写
C程序由一条条语句构成,每个语句以”;”结束
大括号都是成双成对出现的,却一不可
C常用的转义字符
\t:一个制表位,实现对齐的功能
\n:换行符
\\:一个\
\“:一个“
\‘:一个’
\r:一个回车 printf(“张无忌赵民周\r芷若小赵”); 输出结果是”芷若小赵民周”
学习编程最容易犯的错是语法错误,c语言要求必须按照语法规则编写代码。如果你的程序违反了语法规则,例如:忘记了分号,大括号,引号,或者拼错了单词,c编译器都会报语法错误,尝试着去看懂编译器报告的错误信息
C语言注释
介绍:用于注解说明解释程序的文字就是注释,注释提高了代码的阅读性;
注释是一个程序员必须要具有的良好编程习惯。将自己的思想通过注释先整理出来,再用代码实现
有单行注释和多行注释两种
1 | //表示单行注释 |
规范代码风格
正确的注释和注释风格:
如果注释的一个函数,可以使用多行注释
如果注释函数中的某一条语句,可以使用单行注释
正确的缩进和空白:
使用一次tab操作,实现缩进,默认整体向右移动,按shift+tab可以整体向左移
运算符习惯性的两边各加一个空格
有两种代码风格:
1 | include<stdio.h> |
C语言标准库
C标准库是一组C内置函数,常量的头文件,比如<stdio.h>,<stdlib.h>,<math.h> 等等。这个标准库可以作为C程序员的参考手册
可参考C标准库 参考手册来查看。
程序实例:
1 |
|
C 标准库 – 参考手册 | 菜鸟教程 (runoob.com)
变量和常量
变量快速入门
一个程序就是一个世界,不论是使用哪种高级程序语言编写程序,变量都是其程序的基本组成单位,比如:
1 |
|
简单的原理示意图
变量使用的基本步骤
声明变量
int num;
赋值
num = 60;
使用
printf(“num=%d”,num);
1 |
|
变量的注意事项
- 变量表示内存中的一个存储区域(不同的数据类型,占用的空间大小不一样)
- 该区域有自己的名称和类型
- 变量必须先声明,后使用
- 该区域的数据可以在同一类范围内不断变化
- 变量在同一个作用域内不能重名
- 变量三要素(变量名+值+数据类型),这一点请大家注意。
1 | #include<stdio.h> |
变量的数据类型
每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(使用字节多少表示)
注意:在c中,没有字符串类型,使用字符数组表示字符串
在不同的系统上,部分数据类型字节长度不一样,int 2或者4个字节
基本数据类型
整数类型
C语言的整数类型就是用于存放整数值的,比如10,30,22,55
char的数据在底层也是使用整数来存放的
类型 | 存储大小 | 值范围 |
---|---|---|
char | 1 字节 | -128 到 127 或 0 到 255 |
unsigned char | 1 字节 | 0 到 255 |
signed char | 1 字节 | -128 到 127 |
int | 2 或 4 字节 | -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647 |
unsigned int | 2 或 4 字节 | 0 到 65,535 或 0 到 4,294,967,295 |
short | 2 字节 | -32,768 到 32,767 |
unsigned short | 2 字节 | 0 到 65,535 |
long | 4 字节 | -2,147,483,648 到 2,147,483,647 |
unsigned long | 4 字节 | 0 到 4,294,967,295 |
1 |
|
C语言基本数据类型C99
整型的使用细节
各种类型的存储带下与操作系统,系统位数和编译器有关,目前通用的以64为系统为主。
在实际工作中,c程序通常运行在linux/unix操作系统下,在考试中使用windows
Windows vc12 | Linux gcc-5.3.1 | Linux gcc-5.3.1 | Compiler |
---|---|---|---|
win32 x64 | i686 | x86_64 | target |
1 | 1 | 1 | char |
1 | 1 | 1 | unsigned char |
2 | 2 | 2 | short |
2 | 2 | 2 | unsigned short |
4 | 4 | 4 | int |
4 | 4 | 4 | unsigned int |
4 | 4 | 8 | long |
4 | 4 | 8 | unsigned long |
4 | 4 | 4 | float |
8 | 8 | 8 | double |
4 | 4 | 8 | long int |
8 | 8 | 8 | long long |
8 | 12 | 16 | long double |
C语言的整数类型,分为有符号和无符号两种,默认是signed
C程序中整型常声明为int型,除非不足以表示大数,才使用long long
bit:计算机中最小的存储单位,byte(字节):计算机中基本存储单元。1bit = 8bit
【二进制再详细说,简单举例一个short和int】
short s = 3在内存中占用2个字节,一个字节有8个比特,就占用了16个bit
int i = 3在内存中占用4个字节,一个字节有8个比特,就占用了32个bit
浮点类型
C语言的浮点类型可以表示一个小数,比如123.4,6.8,0.12等等
浮点型的分类
类型 | 存储大小 | 值范围 | 精度 |
---|---|---|---|
float | 4字节 | 1.2E-38到3.4E+38 | 6位小数 |
double | 8字节 | 2.3E-308到1.7E+308 | 15位小数 |
说明一下:
关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
尾数部分可能丢失,造成精度损失
浮点数使用细节
浮点数常量默认为double型,声明float型常量时,须后加 f 或 F。
浮点型常量有两种表示形式
十进制数形式:如:5.12 512.0f .512(必须有小数点)
科学计数法形式:如:5.12e2,5.12E-2
通常情况下,应该使用double型,因为它比float型更精确
printf(“d1=%f”,d1); 在输出时,默认保留小数点6位
1 |
|
字符类型
字符类型可以表示单个字符,字符类型是char,char是1个字节(可以存字母或者数字)多个字符称为字符串,在c语言中 使用char数组表示,数组不是基本数据类型,而是构造类型【数组我们后面讲解】
字符常量使用单引号括起来的单个字符。
c语言中还允许使用转义字符,\ 来将其后的字符转变为特殊字符型常量。例如:char c3 = ’\n’ ;
在c中,char的本质是一个整数,在输出时,是ascll码对应的字符。
可以直接给char赋一个整数,然后输出时,会按照对应的ascll字符输出【97】
char类型时可以进行运算的,相当于一个整数,因为它都有对应的unicode码。
ASCII码介绍(了解)
二进制 | 十进制 | 十六进制 | 字符/缩写 | 解释 |
---|---|---|---|---|
00000000 | 0 | 00 | NUL (NULL) | 空字符 |
00000001 | 1 | 01 | SOH (Start Of Headling) | 标题开始 |
00000010 | 2 | 02 | STX (Start Of Text) | 正文开始 |
00000011 | 3 | 03 | ETX (End Of Text) | 正文结束 |
00000100 | 4 | 04 | EOT (End Of Transmission) | 传输结束 |
00000101 | 5 | 05 | ENQ (Enquiry) | 请求 |
00000110 | 6 | 06 | ACK (Acknowledge) | 回应/响应/收到通知 |
00000111 | 7 | 07 | BEL (Bell) | 响铃 |
00001000 | 8 | 08 | BS (Backspace) | 退格 |
00001001 | 9 | 09 | HT (Horizontal Tab) | 水平制表符 |
00001010 | 10 | 0A | LF/NL(Line Feed/New Line) | 换行键 |
00001011 | 11 | 0B | VT (Vertical Tab) | 垂直制表符 |
00001100 | 12 | 0C | FF/NP (Form Feed/New Page) | 换页键 |
00001101 | 13 | 0D | CR (Carriage Return) | 回车键 |
00001110 | 14 | 0E | SO (Shift Out) | 不用切换 |
00001111 | 15 | 0F | SI (Shift In) | 启用切换 |
00010000 | 16 | 10 | DLE (Data Link Escape) | 数据链路转义 |
00010001 | 17 | 11 | DC1/XON (Device Control 1/Transmission On) | 设备控制1/传输开始 |
00010010 | 18 | 12 | DC2 (Device Control 2) | 设备控制2 |
00010011 | 19 | 13 | DC3/XOFF (Device Control 3/Transmission Off) | 设备控制3/传输中断 |
00010100 | 20 | 14 | DC4 (Device Control 4) | 设备控制4 |
00010101 | 21 | 15 | NAK (Negative Acknowledge) | 无响应/非正常响应/拒绝接收 |
00010110 | 22 | 16 | SYN (Synchronous Idle) | 同步空闲 |
00010111 | 23 | 17 | ETB (End of Transmission Block) | 传输块结束/块传输终止 |
00011000 | 24 | 18 | CAN (Cancel) | 取消 |
00011001 | 25 | 19 | EM (End of Medium) | 已到介质末端/介质存储已满/介质中断 |
00011010 | 26 | 1A | SUB (Substitute) | 替补/替换 |
00011011 | 27 | 1B | ESC (Escape) | 逃离/取消 |
00011100 | 28 | 1C | FS (File Separator) | 文件分割符 |
00011101 | 29 | 1D | GS (Group Separator) | 组分隔符/分组符 |
00011110 | 30 | 1E | RS (Record Separator) | 记录分离符 |
00011111 | 31 | 1F | US (Unit Separator) | 单元分隔符 |
00100000 | 32 | 20 | (Space) | 空格 |
00100001 | 33 | 21 | ! | |
00100010 | 34 | 22 | “ | |
00100011 | 35 | 23 | # | |
00100100 | 36 | 24 | $ | |
00100101 | 37 | 25 | % | |
00100110 | 38 | 26 | & | |
00100111 | 39 | 27 | ‘ | |
00101000 | 40 | 28 | ( | |
00101001 | 41 | 29 | ) | |
00101010 | 42 | 2A | * | |
00101011 | 43 | 2B | + | |
00101100 | 44 | 2C | , | |
00101101 | 45 | 2D | - | |
00101110 | 46 | 2E | . | |
00101111 | 47 | 2F | / | |
00110000 | 48 | 30 | 0 | |
00110001 | 49 | 31 | 1 | |
00110010 | 50 | 32 | 2 | |
00110011 | 51 | 33 | 3 | |
00110100 | 52 | 34 | 4 | |
00110101 | 53 | 35 | 5 | |
00110110 | 54 | 36 | 6 | |
00110111 | 55 | 37 | 7 | |
00111000 | 56 | 38 | 8 | |
00111001 | 57 | 39 | 9 | |
00111010 | 58 | 3A | : | |
00111011 | 59 | 3B | ; | |
00111100 | 60 | 3C | < | |
00111101 | 61 | 3D | = | |
00111110 | 62 | 3E | > | |
00111111 | 63 | 3F | ? | |
01000000 | 64 | 40 | @ | |
01000001 | 65 | 41 | A | |
01000010 | 66 | 42 | B | |
01000011 | 67 | 43 | C | |
01000100 | 68 | 44 | D | |
01000101 | 69 | 45 | E | |
01000110 | 70 | 46 | F | |
01000111 | 71 | 47 | G | |
01001000 | 72 | 48 | H | |
01001001 | 73 | 49 | I | |
01001010 | 74 | 4A | J | |
01001011 | 75 | 4B | K | |
01001100 | 76 | 4C | L | |
01001101 | 77 | 4D | M | |
01001110 | 78 | 4E | N | |
01001111 | 79 | 4F | O | |
01010000 | 80 | 50 | P | |
01010001 | 81 | 51 | Q | |
01010010 | 82 | 52 | R | |
01010011 | 83 | 53 | S | |
01010100 | 84 | 54 | T | |
01010101 | 85 | 55 | U | |
01010110 | 86 | 56 | V | |
01010111 | 87 | 57 | W | |
01011000 | 88 | 58 | X | |
01011001 | 89 | 59 | Y | |
01011010 | 90 | 5A | Z | |
01011011 | 91 | 5B | [ | |
01011100 | 92 | 5C | \ | |
01011101 | 93 | 5D | ] | |
01011110 | 94 | 5E | ^ | |
01011111 | 95 | 5F | _ | |
01100000 | 96 | 60 | ` | |
01100001 | 97 | 61 | a | |
01100010 | 98 | 62 | b | |
01100011 | 99 | 63 | c | |
01100100 | 100 | 64 | d | |
01100101 | 101 | 65 | e | |
01100110 | 102 | 66 | f | |
01100111 | 103 | 67 | g | |
01101000 | 104 | 68 | h | |
01101001 | 105 | 69 | i | |
01101010 | 106 | 6A | j | |
01101011 | 107 | 6B | k | |
01101100 | 108 | 6C | l | |
01101101 | 109 | 6D | m | |
01101110 | 110 | 6E | n | |
01101111 | 111 | 6F | o | |
01110000 | 112 | 70 | p | |
01110001 | 113 | 71 | q | |
01110010 | 114 | 72 | r | |
01110011 | 115 | 73 | s | |
01110100 | 116 | 74 | t | |
01110101 | 117 | 75 | u | |
01110110 | 118 | 76 | v | |
01110111 | 119 | 77 | w | |
01111000 | 120 | 78 | x | |
01111001 | 121 | 79 | y | |
01111010 | 122 | 7A | z | |
01111011 | 123 | 7B | { | |
01111100 | 124 | 7C | | | |
01111101 | 125 | 7D | } | |
01111110 | 126 | 7E | ~ | |
01111111 | 127 | 7F | DEL (Delete) | 删除 |
在计算机内部,所有数据都使用二进制表示。每一个二进制位(bit)有0和1两种状态,因此8个二进制位就可以组合出256种状态,这被称为一个字节(byte),一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111.
ASCII码,上个世纪60年代,美国指定了一套字符编码,对英语字符与二进制之间的关系,做了统一规定。这被称为ASCII码。ASCII码一共规定了127个字符的编码,比如空格”SPACE“是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定位0.
缺点:不能表示所有字符,相同的编码表示的字符不一样,比如130在法语编码中代表了e,在希伯来语编码中却代表了字母Gimel
1 |
|
字符类型本质探讨
字符型存储到计算机中,需要将字符对应的码值(整数)找出来存储:字符’a’ -> 码值(97) -> 二进制(1100001) -> 存储() 读取:二进制(1100001) -> 码值(97) -> 字符‘a’ -> 读取(显示)
字符和码值的对应关系是通过字符编码表决定的(是规定好)
布尔类型
在 C 语言标准(C89)没有定义布尔类型,所以 C 语言判断真假时以 0 为假,非 0 为真。所以我们通常使用逻辑变量的做法:
但这种做法不直观。所以我们可以借助 C 语言的宏定义:
所以在最新的 C 语言标准(C99)解决了布尔类型的问题。C99 提供了 _Bool 型,所以布尔类型可以声明为 _Bool flag。
_Bool 依然仍是整数类型,但与一般整型不同的是,_Bool 变量只能赋值为 0 或 1,非 0 的值都会被存储为 1。
C99还提供了一个头文件 <stdbool.h> 定义了 bool 代表 _Bool,true 代表 1,false 代表 0。只要导入 stdbool.h ,就能非常方便的操作布尔类型了。
1 |
|
C99导入相关的库
1 |
|
C语言的布尔类型(bool) (runoob.com)
基本数据类型的转换
自动类型转换:当C程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个就是自动类型转换。
数据类型按精度(容量)大小排序为
数据类型自动转换表
自动转换的细节说明
有多种类型的数据混合运算时,系统首先自动将所有数据转换成激动最大的那种数据类型,然后再进行计算(如int型和short型运算时,先把short转成int型后再进行计算)
如果两种类型的字节数不同,转换成字节数大的类型,若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
再赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型,如果右边变量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入
1 |
|
强制类型转换
将精度高的数据乐星转换为精度小的数据类型。使用时要加上强制转换符() ,但是可能造成精度降低或溢出,格外要注意。
格式如下:(类型名)表达式
这种强制类型转换操作并不改变操作数本身
1 |
|
强制类型转换细节说明
当进行数据的从精度高—>精度低,就需要使用强制转换
强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
1 | int x = (int)10*3.5+6*1.5; |
指针入门
本身指针需要放在后面讲解,但是授课很快就会使用到指针的概念,因此先对指针做一个入门讲解(后面还会详细讲解的),简单的说指针表示指向一个地址,举例说明:
1 |
|
指针的应用案例和细节
写一个程序,获取一个int变量的num的地址,并显示到终端
将num的地址赋给指针ptr,并通过ptr去修改num的值
并画出案例的内存布局图
1 |
|
指针的细节
基本类型,都有对应的指针类型,形式为数据类型 *,比如int的对应的指针就是 int * ,float对应的指针类型就是 float *,以此类推。
此外还有指向数组的指针,指向结构体的指针,指向共用体的指针,(二级指针,多级指针)后面我们再讲到数组,结构体和共用体时,还会再次详细讲解。
值传递和地址传递
值传递:将变量指向的存储内容,再传递、赋值时,拷贝一份给接收变量。
地址传递也叫指针传递:如果是指针,就将指针变量存储的地址,传递给接送变量,如果是数组,就将数组的首地址传递给接收变量。
C语言传递参数(或者赋值)可以是值传递(pass by value),也可以传递指针(a pointer passed by value),传递指针也叫地址传递。
默认传递值的类型:基本数据类型(整数类型,小数类型,字符类型),结构体,共用体。
默认传递地址的类似:指针,数组
1 | int num1 = 100; |
1 | int num = 100; |
常量的基本介绍
常量是固定值,在程序执行期间不能改变,这些固定的值,又叫做字面量。
常量可以是任何的基本数据类型,比如整数常量,浮点常量,字符常量,或字符串字面值,也有枚举常量。
常量的值在定义后不能进行修改。
整数常量可以是十进制,八进制或十六进制的常量,前缀指定基数,0x或ox表示十六进制,0表示八进制,不带前缀则默认表示十进制。整数常量也可以带一个后缀,后缀是U和L的组合,U表示无符号整数(unsigned),L表示长整数(long),后缀可以是大写,也可以是小写,U和L的顺序任意
整数常量举例说明
85 十进制
0213 八进制
0x4b 十六进制
30 整数
30u 无符号整数
30l 长整数
30ul 无符号长整数
1 | int main(){ |
浮点常量
浮点常量由整数部分,小数点,小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。
浮点常量举例说明
1 | 3.14159; //double常量 |
字符常量
字符常量是括在单引号中,例如,‘x’可以存储在char类型的变量中。字符常量可以是一个普通的字符(例如’x’),一个转义序列(例如’ \t ‘)
字符常量举例说明
1 | 'X'; |
字符串常量
字符串字面值或常量是括在双引号“”中的。一个字符串包含类似于字符常量的字符:普通的字符,转义字符和通用的字符。可以使用空格做分隔符,把一个很长的字符串常量进行分行
字符串常量的举例说明
1 | "hello world"; |
常量的定义
使用#define预处理器
1 |
|
使用const关键字
1 |
|
const和define的区别
const定义的常数带类型,define不带类型
const是在编译,运行的时候起作用,而define是在编译的预处理阶段起作用
define只是简单的替换,没有类型检查。简单的字符串替换会导致边界效应
const常量可以进行调试的,define是不能进行调试的,主要是预处理阶段就已经替换掉了,调试的时候就没它了
const不能重定义,不可以定义两个一样的,而define通过undef取消某个符号的定义,再重新定义
define可以配合#ifdef,#ifndef,#endif来使用,可以让代码更加灵活,比如我们可以通过#define来启动或者关闭调试信息。
1 |
|
1 |
|
运算符和逻辑语句
运算符是一种特殊的符号,用以表示数据的运算,赋值和比较等。
算术运算符 (+,-,*,/,%)
赋值运算符 (= += -=)
关系运算符 (> >= < <= ==)
逻辑运算符 (&& || !)
位运算符 (& 按位与 | 按位或 ^ 按位异或 ~按位取反等等)
三元运算符 (表达式 ?表达式1 :表达式2)
运算符 | 描述 | 实例 |
---|---|---|
+ | 把两个操作数相加 | A + B 将得到 30 |
- | 从第一个操作数中减去第二个操作数 | A - B 将得到 -10 |
* | 把两个操作数相乘 | A * B 将得到 200 |
/ | 分子除以分母 | B / A 将得到 2 |
% | 取模运算符,整除后的余数 | B % A 将得到 0 |
++ | 自增运算符,整数值增加 1 | A++ 将得到 11 |
– | 自减运算符,整数值减少 1 | A– 将得到 9 |
运算符 | 描述 | 实例 |
---|---|---|
== | 检查两个操作数的值是否相等,如果相等则条件为真。 | (A == B) 为假。 |
!= | 检查两个操作数的值是否相等,如果不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) 为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) 为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) 为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A <= B) 为真。 |
运算符 | 描述 | 实例 |
---|---|---|
&& | 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 | (A && B) 为假。 |
|| | 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 | (A || B) 为真。 |
! | 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 | !(A && B) 为真。 |
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与操作,按二进制位进行”与”运算。运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1; |
(A & B) 将得到 12,即为 0000 1100 |
| | 按位或运算符,按二进制位进行”或”运算。运算规则:`0 | 0=0; 0 |
^ | 异或运算符,按二进制位进行”异或”运算。运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0; |
(A ^ B) 将得到 49,即为 0011 0001 |
~ | 取反运算符,按二进制位进行”取反”运算。运算规则:~1=-2; ~0=-1; |
(~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。 |
<< | 二进制左移运算符。将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。 | A << 2 将得到 240,即为 1111 0000 |
>> | 二进制右移运算符。将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。 | A >> 2 将得到 15,即为 0000 1111 |
运算符 | 描述 | 实例 |
---|---|---|
== | 检查两个操作数的值是否相等,如果相等则条件为真。 | (A == B) 为假。 |
!= | 检查两个操作数的值是否相等,如果不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) 为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) 为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) 为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A <= B) 为真。 |
运算符 | 描述 | 实例 |
---|---|---|
sizeof() | 返回变量的大小。 | sizeof(a) 将返回 4,其中 a 是整数。 |
& | 返回变量的地址。 | &a; 将给出变量的实际地址。 |
* | 指向一个变量。 | *a; 将指向一个变量。 |
? : | 条件表达式 | 如果条件为真 ? 则值为 X : 否则值为 Y |
C 运算符 | 菜鸟教程 (runoob.com)
键盘输入语句
在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。
步骤:写入头文件 include<stdio.h> , 使用scanf函数 , 使用适当的格式参数接收输入
1 |
|
进制转换和位运算
对于整数,有四种表示方式
二进制:0,1,满二进一,C语言没有二进制常数的表示方法
十进制:0,9,满十进一
八进制:0,7,满8进一
十六进制:0-9,A-F,满十六进一,以0x开头表示,A-F表示10-15
进制转换
二进制转十进制
从最低位开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和。
1011 = 1 * 2 ^ 0 + 1 * 2 ^ 1 + 0 * 2 * 2 + 1 * 2 ^ 3 = 1 + 2 + 0 + 8 = 11
八进制转十进制
从最低位开始,将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和。
0123 = 3 * 8 ^ 0 + 2 * 8 ^ 1 + 1 * 8 ^ 2 = 3 + 16 + 64 = 83
十六进制转十进制
从最低位开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和。
0x34A = 10 * 16 ^ 0 + 4 * 16 ^ 1 + 3 * 16 ^ 2 = 10 + 64 + 768 = 842
十进制转二进制
将该数不断除以2,直到商为0止,然后将每步得到的余数倒过来,就是对应的二进制。
56 = 56 / 2 = 28余0 / 2 = 14余0 / 2 = 7余0 / 2 = 3余1 % 2 = 1余1 % 2 = 0余1;
倒过来只看余数就是 111000
十进制转八进制
将该数不断除以8,直到商为0止,然后将每步得到的余数倒过来,就是对应的八进制。
156 = 156 / 8 = 19余4 / 8 = 2余3 / 8 = 0余数2 = 234
十进制转十六进制
将该数不断除以16,直到商为0止,然后将每步得到的余数倒过来,就是对应的十六进制。
356 = 356 / 16 = 22余4 / 16 = 1余6 / 16 = 0余1 = 164
二进制转八进制
从最低位开始,将二进制数每三位一组,转成对应的八进制数即可。
011010101 011 = 3 010 = 2 101 = 5 结果是 325
二进制转十六进制
从最低位开始,将二进制数每四位一组,转成对应的八进制数即可。
11010101 1101 = 13 0101 = 5 结果是D5
八进制转二进制
将八进制数每一位,转成对应的一个3位的二进制数即可。
0237 = 00 + 10 + 011 + 111 = 10011111
十六进制转二进制
将十六进制数每一位,转成对应的一个4位的二进制数即可。
0x23B = 0010 + 0011 + 1011 = 1000111011
源码反码和补码
1 | //一些测试题 |
网上对源码,反码,补码的解释过于复杂,我这里精简几句话:
对于有符号的而言:
- 二进制的最高位是符号位:0表示整数,1表示负数
- 正数的原码,反码,补码都一样(三码合一)
- 负数的反码=它的源码符号位不变,其他位取反(0变1,1变0)
- 负数的补码=他的反码+1,负数的反码=他的补码-1
- 0的反码,补码都是0
- 在计算机运算的时候,都是以补码的方式来运算的
1 | ~2 = ?; |
程序流程控制
在程序中,程序运行的刘崇控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控制语句:
顺序控制
顺序控制是程序从上到下逐行的执行,中间没有任何判断和跳转。
分支控制
分支控制有选择分支的执行,分支控制有三种:
单分支,双分支,和多分支
单分支
1 | if(条件表达式){ |
当条件表达式为真(非0)时,就会实行{} 的代码,返回假(0)时,不会执行{} 的代码
双分支
1 | if(条件表达式){ |
当条件表达式为真(非0)时,就会实行代码块1,否则实行代码块2
多分支
1 | if(条件表达式1){ |
嵌套分支
1 | if(){ |
switch分支
1 | switch(表达式){ |
1 | #include<stdio.h> |
循环分支
就是让你的代码可以循环的执行
for循环
1 | for(1循环变量初始化;2循环条件;4循环变量迭代){ |
1 |
|
While循环
1 | 循环变量初始化; |
1 |
|
1 |
|
doWhile循环
1 | 循环变量初始化; |
1 |
|
多重循环控制
将一个循环放在另一个循环体内,就形成了嵌套循环,最多三层。
嵌套循环就是把内存循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可以结束外层的本次循环,开始下一次的循环。
1 | #include <stdio.h> |
空心菱形三角
1 |
|
跳转控制语句
break
break用于终止某个代码块的执行,一般使用在switch或者循环中。
1 |
|
实现简单的登录验证
1 |
|
C 库函数 – strcmp() | 菜鸟教程 (runoob.com)
Continue
continue用于结束本次循环,继续执行下一次循环
continue不能单独在switch或if中使用
1 |
|
goto和return语句
goto语句可以无条件的转移到程序中指定的行。
goto语句通常与条件语句配合使用。可用来条件转义,跳出循环体等功能。
C程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难
1 |
|
return使用在函数,表示跳出所在的函数。
1 |
|
枚举
引出枚举
举个例子,比如:一星期有7天,请定义数据表示星期一到星期天
传统的方法
使用#define完成,这个代码量比较多,并且不好管理,在此引出了枚举
1 |
枚举介绍
枚举是C语言中的一种构造数据类型,它可以让数据更简介,更易懂,对于只有几个有限的特定数据,可以使用枚举。
枚举对应英文enumeration,简写enum
枚举是一组常量的集合,包含一组有限的特定的数据
枚举语法定义格式为
enum 枚举名{枚举元素1,枚举元素2,……};
1 |
|
枚举的遍历
C语言中,枚举类型是被当作int或者unsigned int类型来处理的,枚举类型必须连续是可以实现有条件的便利。以下实例使用for来遍历枚举的元素
1 |
|
枚举在switch中使用
1 |
|
枚举的细节
第一个枚举成员的默认值为整形的0,后续枚举成员的值在前一个成员上加1,我们在这个示例中把第一个枚举成员的值定义为1,第二个就为2,以此类推。
在定义枚举类型时改变枚举元素的值。
枚举变量的定义的形式1-先定义枚举类型,再定义枚举变量。
1 | enum DAY{ |
枚举变量的定义的形式2-定义枚举类型的同时定义枚举变量。
1 | enum DAY{ |
枚举变量的定义形式3-省略枚举名称,直接定义枚举变量。
1 | enum{ |
可以将整数转换为对应的枚举值
1 |
|