目录
1)当int型或long型的(字节数>=4)发生有无符号数转换
2)当char型或short型的(字节数<4)发生有无符号数转换
一、怎么在终端编译.c文件
1、vim(编辑器)
格式:
vim 文件名 打开或创建一个文件
2、引入头文件
include" " 先查看当前目录,再查看库路径
include<>直接查看库路径
3、头文件引入路径
/usr/include/
4、函数的格式
打入 main Tab键,可以补全main函数基础格式
int main(int argc,const char *argv[])
{
return 0
}
第一个参数:函数类型 为int型
第二个参数:函数名 main(保证唯一性)
第三个参数:函数外部变量的类型 为int型
第四个参数:函数外部变量 argc(存储外部参数的个数)
argv(存储外部传递的参数)
第五个参数:返回值 return(返回值的类型和函数的类型一致)
return也可以代表函数的结束
最后return的值为0代表正常结束 return的值为1代表异常
5、索引关键字的字库
vi字库里存储着常用的关键字,可以用Tab键补全
gedit ~/.vim/snippets/c.snippets //以文本模式打开 好用
1)如何进入字库查看
输入命令:vi ~/.vim/snippets/c.snippets 即可
2)添加自己需要的字库
第一步输入命令:vi ~/.vim/snippets/c.snippets
第二步:进入vi文件,点击G进入到最后一行
第三步:点击p/a/i会打开,灰色线的隐藏代码
第四步:在主函数上面加入头文件
第五步::wq保存即可
6、gcc(编译器)
gcc编译过程:预处理----->编译---->汇编----->链接
1)直接输出可执行文件
gcc ****.c 默认生成一个二进制可执行文件 a.out (类似于 keil5 的Hex文件)
2)指定输出可执行文件名运行
gcc ****.c -o 制定可执行文件名
gcc会解析编辑的代码,如果有错误会显示error,如果有警告会显示warning
建议显示warning,因为warning的多少代表了代码的规范程度,出现warning是因为代码不规范
3)执行可执行文件
./要执行的可执行文件名
4)-Wall(显示所有警告,实际上是一组警告)
gcc ****.c -o 制定可执行文件名 -Wall
5)-Werror(把警告改为报错)
gcc ****.c -o 制定可执行文件名 -Werror
gcc ****.c -o 制定可执行文件名 -Wall -Werror
6)gcc的分步编译
gcc编译的本质 gcc编译的过程经过了四步
-E -S -C .i .s .o
预处理 >> 编译 >> 汇编 >> 目标文件 >> 可执行链接
gcc -E ***.c -o ***.i
预处理:展开头文件 删除注释 进行宏替换 生成.i文件
gcc -S ***.i -o ***.s
编译:检查语法的正确性 判断语法是否合规 生成.s文件(.s文件是汇编文件)
gcc -C ***.i -o ***.o
汇编:将汇编文件 转成二进制文件 生成.o文件 目标文件(.o文件是二进制文件)
gcc ***.o -o ***
链接:将二进制文件 转成可执行文件
7、执行文件
格式:
./可执行函数名
执行可执行文件,输出在终端
二、进制
1、什么是进制
按某种方式实现进制的方法
二进制 八进制 十进制 十六进制 二十四进制 。。。。
进制:数码,基数,位权
0153
基数:10
数码:0--9
位权:10^2 10^1 10^0
2、进制转换
N进制转十进制 使用乘权相加法
十进制转N进制 除N逆向取余
二进制转为八进制(421)或十六进制(8421) 使用8421码转换
八进制(421)或十六进制(8421) 转为二进制 使用8421码转换
三、有无符号数
1、有无符号数:
以char型举例
无符号数:无正负之分所有位均表示数值,就像绝对值
范围:[0,255] 最大值:255 最小值:0
有符号数:有正负之分,最高位表示正负(0表示正,1表示负),其余位表示数值
范围:[-128,127] 最大值:127 最小值:-128
2、计算机的运算
计算机默认只有加法器运算(或运算)
原码:最高位表示符号位,其余为表示数值位
反码:最高位不变,对原码取反
补码:对反码加1
正数的原反补一样
计算机的计算流程
3-5---->3+(-5)
3--->原---》反---》补
3:11
原:00000011
反:00000011
补:00000011
-5--》原---》反--》补
-5:101
原:10000101
反:11111010
补:11111011
补码相加---》反---》原---》十进制
补:00000011
补:11111011
------------
11111110 ---》补
11111101 ----》反
10000010 ----》原----》-2
四、数据类型
1、什么是数据类型
不同的数据需要使用不同的数据类型存储,目的:方便查找,存储
2、数据分类
基本类型:数据不可分割(数值,字符串,枚举)
构造类型:数据可分割(数组,结构体,共用体)
空类型:void类型,一般使用与参数和返回值
指针类型:指针
3、数据关键字
整数 | 名称 | 占位符 | 字节大小 | 取值范围 |
int --->signed int | 有符号整数 | %d %i %#o %#x | 4 | -2^31,+(2^31)-1 |
unsigned int | 无符号数 | %u | 4 | 0,(2^32)-1 |
short-->signed short int | 有符号短整型 | %d | 2 | -2^15,+(2^15)-1 |
unsigned short | 无符号短整型 | %u | 2 | 0,(2^16)-1 |
long-->signed long int | 有符号长整型 | %ld | 在32位操作系统4 在64位操作系统8 | -2^63,+(2^63)-1 |
unsigned long | 无符号长整形 | %lu | 在32位操作系统4 在64位操作系统8 | 0,(2^64)-1 |
long long | 无符号长整型 | %ld | 8 | -2^63,+(2^63)-1 |
unsigned long long | 有符号长整型 | %lu | 8 | 0,(2^64)-1 |
小数\实数\浮点数 | 名称 | 占位符 | 字节大小 | 有效位 (包括整数部分 超出有效位会乱) |
float | 单精度浮点型 | %f | 4 | 6-7 |
double | 双精度浮点型 | %lf | 8 | 15-16 |
字符 | 名称 | 占位符 | 字节大小 | 取值范围 |
char -->signed char | 字符 | %c | 1 | -128,127 |
unsigned char | 字符 | %c %u | 1 | 0,255 |
字符串 | %s |
4、 特殊的占位符:
使用printf时
%-10d 10 代表占10个字符的位置,- 代表向左对齐,剩余的用空格填充
%10d 10 代表占10个字符的位置,+ 代表向右对齐,剩余的用空格填充
%05d 5 代表占 5个字符的位置,+ 代表向左对齐,剩余的用 0 填充
%.2f .2 代表输出小数点后两位
特殊的:
printf("%*d", width, num); // 等价于 printf("%5d", num);
使用scanf时
%*c 是占位符,吸收字符
%*d 动态跳过,吸收整数 接收这个位置的参数,但是不赋值给变量
五、宏
1、宏的概念
宏:是一个常量
宏只做替换,不做计算,不做正确的检测(发生在预处理这一步,默认为全局变量)
编译过程中在预处理这一步,会替换宏,就是将宏定义,替换到函数中的宏去
2、宏定义
格式:
#define 宏名 宏体
解析:
1.#define 固定的,预处理命令
2.宏名:满足命名规范(由数字,字母下划线,不可以是关键字,区分大小写,见名知意)
默认宏大写,变量小写,函数名驼峰或下划线链接
1、定义数值常量
#define NUM 100
2、定义字符常量 ' '单引号只能解析单个字符
#define STR 'D'
3、定义字符串常量 " "双引号能解析多个字符
#define STR2 "ABCD"
3、常见的已经定义的宏
宏名 功能 所用的占位符
__LINE__: 打印行号的(后期修改bug用) %d
__FILE__: 打印文件名 %s
__func__:打印函数名 %s
__DATE__:打印日期 年月日 %s
__TIME__:打印时间 时分秒 %s
六、变量
1、变量的格式(存储类型)
格式:存储类型 数据类型 变量名
int num (默认是auto型)
存储类型:
auto:自动类型,当局部变量不写数据类型是,默认是auto
extern:引用外部变量
static:静态变量
register:寄存器变量,有可寻址位和不可寻址位
const:修饰的变量不可变
volatile:防止内存优化,保持内存的可见性
数据类型:基本类型 int,char,float,shout
变量名:满足规范即可
2、整数变量
1.定义一个变量
int a=100;
2.定义多个变量
int a=100,b,c;
3.变量数据溢出
最大值溢出时,会从最大值越界到最小值
最小值溢出时,会从最小值越界到最大值
3、小数变量
1.float和double直接的区别
float的有效位是6位或7位
double的有效位是15位或16位
%f 和 %lf 默认存在6位小数
2.特殊的占位符
%.3f 精确3个小数位
%.4lf 精确4个小数位
%15.3f 精确3个小数位,数值字符的宽度是15,向右对齐,不足使用空格填充
%-15.3f精确3个小数位,数值字符的宽度是15,向左对齐,不足使用空格填充
4、字符变量
1.字符的变量和初始化
char a='A';
char b=65;
char c=0x41;
char c=0101;
%c(字符型) %d(整数型) %#x(十六进制) %#o(八进制)
2.字符类型的变量赋值依旧会出现数值溢出
3.转义字符
指 '\后面加字符'
例:
'\a' '\b' '\t'
'\n' '\v' '\f' '\r' '\0'
以下也是转移字符,但是没有含义ASCII表不包含
'\c' '\\'
5、类型转换
1)隐式转换
float a=3.99;
int b=a; //计算机会默认把a的值转换为int型,再赋值给b
输出:
b = 3 会舍弃小数部分
2)显示转换
格式:
(数据类型)表达式
float a = 3.99;
int b = (int)a;
输出:
b = 3 会舍弃小数部分
3)计算机转换流程及存储方式
补充知识点:
大端存储:地址低位存储数据高位,地址高位存储数据低位(例:网络传输)
小端存储:地址高位存储数据高位,地址低位存储数据低位(例:计算机的存储)
计算机储存数据的方式:
定义一个int型变量,int a=129
计算机运算需要转成补码 0000 0000 0000 0000 0000 0000 1000 0001
把他转成十六进制 0x00 0x00 0x00 0x81
低位地址 高位地址
地址 0x01 0x02 0x03 0x04
低位数据 高位数据
数据 0x81 0x00 0x00 0x00
char b = (char)a b = 0x81 -127
unsigned char b = (unsigned char)a b = 0x81 129
short b = (short)a b = 0x81 129
6、有无符号数的转换(计算机转换流程)
当有符号数和无符号数发生运算,会自动转换,且计算机的整数形运算默认为int型
1)当int型或long型的(字节数>=4)发生有无符号数转换
当字节数大于4的类型,发生有无符号数运算的转换,会默认转成unsigned型运算
计算机在运算的过程中,需要转换成补码,因为unsigned型没有符号位,所有位都是数据位,
所以要把有符号数 通过 原 反 补 转化成无符号数,进行运算
因此在无符号和有符号之间的运算,负数都特别大
2)当char型或short型的(字节数<4)发生有无符号数转换
当字节数小于4的类型,发生有无符号数运算的转换,会默认转换成int型运算
计算机在运算的过程中,需要转换成补码,因为int型有符号位,所以可以两者可以直接运算
(int型是4字节,小于4字节的运算不会越界)
以上两种情况运算超出定义类型的存储范围,则会发生溢出
注意:(以下情况尽可能避免)
在32位的计算机中,long型是4字节,当long型和unsigned int 型发生有无符号之间的运算,有可能会越界,如果越界,那么计算机会自动向更高位申请数据类型,用unsigned long型运算。
7、输入输出
1)scand输入 printf输出
scanf 输入
格式:
scanf(const char *format, ...)
参数:
const char *format:格式串,一般使用字符或占位符表示
...:可变地址列表:个数可变,类型可变
printf是从右往左编译的
printf 输出
格式:
printf(cost char *format,...);
参数:
const char *format:格式串,一般使用字符或占位符表示
...:可变参数:个数可变,类型可变
2)getchar输入 putchar输出
功能:单字符的输入
格式:
int getchar(void);
返回值:
返回读取字符
功能:单字符的输出
格式:
int putchar(int c);
参数:
c:输出的变量名
七、运算符
运算符的分类:
1、算数运算
+ | 如果运算符的两端表达式都是整数,则最终结果一定是整数。 | 如果运算符的两端表达式有一个小数,则最终结果一定是小数。 |
- | 如果运算符的两端表达式都是整数,则最终结果一定是整数。 | 如果运算符的两端表达式有一个小数,则最终结果一定是小数。 |
* | 如果运算符的两端表达式都是整数,则最终结果一定是整数。 | 如果运算符的两端表达式有一个小数,则最终结果一定是小数。 |
/ | 如果运算符的两端表达式都是整数,则最终结果一定是整数。5/2=2 | 如果运算符的两端表达式有一个小数,则最终结果一定是小数。5.0/2=2.5 |
%取余 | %两端必须是整数 | 5%2=1 5.0%2 error |
自加1 | a++ | 后缀运算,先使用后自增 |
++a | 前缀运算,先自增后运算 | |
自减1 | a-- | 后缀运算,先使用后自减 |
--a | 后缀运算,先自减后运算 |
2、关系运算
> | 条件成立则为1,假为0 |
>= | 条件成立则为1,假为0 |
< | 条件成立则为1,假为0 |
<= | 条件成立则为1,假为0 |
== | 条件成立则为1,假为0 |
!= | 条件成立则为1,假为0 |
3、逻辑运算
优先级:
!> && > ||
0即为假,非假即正
&&逻辑与(且) | 1 && 1=1 1 && 0=0 0 && 1=0 0 && 0=0 | 遇假则假,全真位真 | 当表达式1为假,则不执行表达式2,成为短路效应 |
||逻辑或(或者) | 1 || 1=1 1 || 0=1 0 || 1=1 0 || 0=0 | 遇真则真,全假则假 | 当表达式1为真,则不执行表达式2,成为短路效应 |
!逻辑非 | !0=1 !1=0 | 非真即假 |
4、条件运算\三目运算
格式:
表达式1 ? 表达式2 : 表达式3
逻辑:
表达式1:执行条件
表达式2:如果表达式1条件成立,则执行表达式2
表达式3:如果表达式1条件不成立,则执行表达式3
int a;
scanf("%d",&a);
a%2==0?printf("偶数"):printf("基数");
5、赋值运算
只有自加,自减运算是可以不通过 = 符号赋值的,其他情况都取消通过 = 符号赋值
换而言之,有=符号,就有赋值运算。
注意:
=基本赋值 | a=10 a=b a=b+2 | 把10赋值给变量a, =号的左边只能是变量,右边可以是变量常量表达式 |
+=复合赋值 | a+=2+3 -->a=a+(2+3) | |
-= | a-=2+3--->a=a-(2+3) | |
*= | a*=2+3--->a=a*(2+3) |
6、逗号运算
优先级:
所有运算符中优先级最低
格式:
(表达式1,表达式2,表达式3)
逻辑:
1.每个表达式都执行
2.只输出最后一个表达式作为结果
int a=10;
11 22 7 21
int b=(a++,a*=2,a/3,a-=1);
7、位运算
位运算仅对整数二进制操作
& 按位与 | 1&1=1 1&0=0 0&1=0 0&0=0 | 有一个0,则结果为0 |
|按位或 | 1|1=1 1|0=1 0|1=1 0|0=0 | 有一个1,则结果为1 |
^异或 | 1^1=0 1^0=1 0^1=1 0^0=0 | 相同为0,不同为1 |
~取反 | ~0=1 ~1=0 | 0取反1,1取反0 |
>>右移 | 右移一位除以2 8>>2=2 | 右边多余位舍去,左边最高位是0则补0,是1则补1 |
左移一位乘以2 8 | 左边多余位舍去,右边补0 |
8、运算符的优先级
概括:
括号> 单目运算(单个变量)> 算数运算(加减乘除)> 位移运算(左移右移)>
关系运算(大于小于)> 位运算(按位与>按位异或>按位或)> 逻辑运算(与>或)>
条件运算(三目运算)> 赋值> 逗号
练习:
1.定义宏,实现两个数交换
2.公司的软件项目中,经常需要计算圆的面积,已知圆的半径 r ,请用宏定义的方式编写一个计算圆面积(公式:S=πr2 ,π 取值 3.1415926 )的宏,并说明使用该宏的注意事项。
3.公司网络配置中,IP 地址的子网掩码以二进制 11111111.11111111.11111111.11111000 表示,将其转换为十进制形式,说明计算步骤。192.168.55.60 ip地址就是点分十进制
前三个字节都是8位二进制1111 1111,就是十进制的255
第四个字节:
11111000 用乘权相加解决
1x2^7+1x2^6+1x2^5+1x2^4+1x2^3+1x2^2+1x2^1+1x2^0=248
那么就是 255.255.255.248