1 前言
没啥重要的东西,都是C语言的基础知识;在学习时遇到的问题,整理总结分享一下!
2 编译步骤的分析
编译分为四个步骤:预处理–>编译–>汇编–>链接,每个步骤执行不同得功能任务,生成不同得中间文件。详细情况如下:
1.预处理:注释的删除,头文件的展开,宏定义的替换
gcc -E xxx.c -o xxx.i(生成.l文件)
2.编译:语法分析,词法分析,查错,若无问题生成对应的.s汇编文件
gcc -S xxx.i -o xxx.s(生成.s文件)
3.汇编:将汇编文件翻译成二进制文件
gcc -c xxx.s -o xxx.o(生成.o文件)i
4.链接:链接对应的库文件i
gcc xxx.o -o a.out(生成可执行文件)
3 二进制原反补的计算
数据在储存时会遇到原、反、补码问题。其中存储时得数据分为无符号和有符号两种类型,其中有符号的负数才会涉及到原、反、补的问题。具体情况如下:
1.无符号数:
不涉及负值,原码、反码、补码都一样
2.有符号正数:
原码、反码、补码都一样
3.有符号负数:
反码=原码中符号位不变,数据位按位取反(0变1,1变0)
补码=反码+1
数据在存储和读取时遵循不同的规则,因此要注意对数据的处理,具体的规则是:储存是看正负,取出时看类型(储存数据时看给的数据是正负数,取出时看看定义的是signed还是unsigned,)如signed=129,存进去是129,取出时按129做补码、反码、原码顺序操作,最高位1的实数变为符号位,最终输出-127。
如下是针对各种数据类型在实际计算机存储取出时的规则示例:
#include
int main(int argc, const char *argv[])
{
unsigned char a = 10;
//存储时
//原码: 0000 1010
//反码: 0000 1010
//补码: 0000 1010
//取出时
//补码: 0000 1010
//反码: 0000 1010
//原码: 0000 1010 -->10
printf("a = %d\n", a);//10
signed char b = -10;
//存储时
//原码: 1000 1010
//反码: 1111 0101
//补码: 1111 0110
//取出时
//补码: 1111 0110
//反码: 1111 0101
//原码: 1000 1010 -->-10
printf("b = %d\n", b);//-10
signed char c = 129;
//存储时
//原码: 1000 0001
//反码: 1000 0001
//补码: 1000 0001
//取出时
//补码: 1000 0001
//反码: 1000 0000
//原码: 1111 1111 --> -127
printf("c = %d\n", c);//-127
unsigned char d = -1;
//存储时
//原码: 1000 0001
//反码: 1111 1110
//补码: 1111 1111
//取出时
//补码: 1111 1111
//反码: 1111 1111
//原码: 1111 1111 -->255
printf("d = %d\n", d); //255
return 0;
其中在原、反、补时会涉及到进位,这里以-4为例,做进一步补充:
储存:
原码:1000 0100
反码:1111 1011(原变反,单位不变,数据位按位取反)
补码:1111 1100(反变补,最后一位加一,1+1变2进一位,原位变0,倒2位加1等于2进一,原位变0,进到倒第三位)
取出:
补码:1111 1100
反码:1111 1011(补变反,最后一位减一,不够向前借,借到到第三位,第三位变0,到第二位变2再借剩1,最后一位变2减1等于1,)
原码:1000 0100(按位取反)
总结
有空就更新,敬请期待!!!!