学习C(二)

it2022-05-05  113

学习C(二)

缓冲区GCC编译过程硬链接和软链接getchar()函数define()函数、typedef()函数计算机中二进制的计算(补码的计算)计算类型的最大值

缓冲区

scanf函数和printf函数一样,拥有缓存区:   在终端上输入的数据,并不会直接写入变量中,而是先会写到缓存去中,当遇到回车,再从缓存区写入格式占位符中,最后再从格式占位符写入变量。如果格式占位符与缓存区中第一个数据类型不匹配,则直接跳过接收过程。   所以,无论如何使用scanf,为了结束输入,总是需要输入回车,导致缓存区总是会以回车结尾。   这样就会影响到下一次scanf的使用。所以我们每一次的scanf过后,都需要清理一下缓存:   缓存清理的代码:while(getchar()!='\n'); 例子1:scanf缓存区 #include<stdio.h> int main(){ int num = 5; char ch = 0; scanf("%d",&num); printf("num = %d\n",num); scanf("%c",&ch); printf("ch = %c\n",ch); scanf("%c",&ch); printf("ch = %c\n",ch); scanf("%c",&ch); printf("ch = %c\n",ch); scanf("%d",&num); printf("num = %d\n",num); return 0; }

当输入123\n4567\n时,输出的结果如下: 分析如下:

缓存区123\n4567\n–scanf("%d",&num);scanf("%c",&ch);scanf("%c",&ch);scanf("%c",&ch);scanf("%d",&num);scanf()num接收123ch接收\nch接收4ch接收5num接收67输出num=123ch=\nch=4ch=5num=67

此时缓存区还剩下\n

例子2:scanf缓存清理

#include<stdio.h> int main(){ int num = 5; char ch = 0; scanf("%d",&num); while(getchar()!='\n'); /* getchar函数能够从终端获取单一字符,无论输入多少字符,永远只能获取第一个。 当getchar成功获取到字符后,getchar()就可以看做一个数学表达式, 这个表达式的值就是获取的字符的值 */ printf("num = %d\n",num); scanf("%c",&ch); while(getchar()!='\n'); printf("ch = %c\n",ch); scanf("%c",&ch); while(getchar()!='\n'); printf("ch = %c\n",ch); return 0; }

当输入123\n4567\n89时(\n代表回车),输出的结果如下: 分析如下:

缓存区1234567\n89\n–scanf("%d",&num);scanf("%c",&ch);scanf("%c",&ch);–while(getchar()!=’\n’);while(getchar()!=’\n’);while(getchar()!=’\n’);scanf()num接收123,\n被清理ch接收4,567\n被清理ch接收8,9\n被清理输出num=123ch=4 其中ch=8

此时缓存区为空

GCC编译过程

gcc编译的具体流程: gcc 编译过程一共分为4个流程:例如现在想要编译的文件名为demo.c   ①:预处理阶段 gcc -E demo.c -o demo.i     gcc的参数:       -E:代表只做预处理,其他都不做       -o:指定输出文件的名字     1:头文件的展开     头文件:该文件中存放了各种库函数的函数声明(头文件中仅仅有函数声明,函数的定义在其他地方)     2:简单宏替换(傻瓜式替换)     什么是宏:使用#define 将一个名字 声明成 一个数据     什么是带参宏:使用#define 将一个带参数的名 声明成 与该参数有关的数学表达式     所有的宏,全都使用大写表示     注意区别#define和typedef       typedef:将一个数据类型,取一个别名       例如:typedef int OI          #define OI int       无论是#define还是typedef,都会使用最后一个数据参与编译(也就是说,#define参与编译的对象是int,typedef参与编译的对象是OI)。在typedef当中,编译器会将OI认定成int进行编译     3:去注释       注释:“//”代表行注释,在“//”之后一整后内容都为注释内容       一组“/” 代表多行注释,写在“/”两个*号内部的内容都为注释     4:上标记:为每一行代码,标记上准确的源文件中的行号       预处理完成之后,生成了预处理文件。注意,预处理仅仅做以上4步,如果程序语法有任何问题,预处理阶段不会做任何干涉   ②:编译阶段:gcc -S demo.i -o demo.s     对预处理文件进行词义,语义及语法分析。当所有语法都正确的情况下,将预处理文件,编译成汇编文件。编译阶段是整个gcc过程中最重要的阶段   ③:汇编阶段:gcc -c demo.s -o demo.o     将汇编文件,转换成计算机能够识别的二进制文件   ④:链接阶段:gcc demo.o -o demo     将二进制文件追加可执行权限,并且转换成可执行文件的格式     并且链接动态库与静态库(仅仅链接动态库与静态库,其他的各种函数库不会默认链接,如果需要使用,注意使用参数 -l+函数库名 去链接函数库)     动态库与静态库中包含了绝大多数的库函数的定义     链接阶段完成后,生成名叫demo的可执行文件

硬链接和软链接

硬链接和软链接:   使用shell ln+源文件名+链接文件名,会为源文件创建一个链接文件,并且名字为链接文件名。   此时,创建出来的链接文件属于硬链接,硬链接是一个普通文件 那么如何创建一个真正的链接文件:使用ln -s参数创建一个软连接   硬链接:他拥有一份源文件的拷贝以及连接到源文件的链接   软链接:他只拥有连接到源文件的链接   当源文件发生改变,硬链接和软链接因为都拥有连接到源文件的链接,所有都会发生改变   当源文件删除时,因为硬链接拥有源文件的拷贝,所以访问硬链接不受影响 但是,软链接只有连接到源文件的链接,所以,软链接无法访问

getchar()函数

#include<stdio.h> int main(){ char ch = getchar(); printf("%c\n",ch); return 0; }

getchar()函数只读取一个字符,即使输入很多个字符也是只读取一个字符,剩下的留在缓存区

define()函数、typedef()函数

#include<stdio.h> #include<pthread.h> #define PI (3+3) #define F(n) ((n)*(n)) #define OOI int typedef int OI; /* 注意,typedef只能为数据类型取别名 */ // tcyhjpl;[]pjgyftchkpl[jgyftghk int main(){ int a = 5; OI b = 5; /* lli c = 10; printf("%lld\n",b); printf("%lld\n",c); */ printf("%d\n",a); printf("%d\n",b); return 0; }

计算机中二进制的计算(补码的计算)

10+6=16

源码反码补码100000 1010 ->->0000 101060000 0110->->0000 0110160001 0000<-<- 0001 0000

10-6=4 即10+(-6)=4 负数补码:源码符号位不变,其余求反加1。即反码加1。

源码反码补码100000 1010 ->->0000 1010-61000 0110 ->1111 1001 ->1111 101040000 0100<-<- 0000 0100

6-10=-4即6+(-10)=-4

源码反码补码60000 0110 ->->0000 0110-101000 1010 ->1111 0101 ->1111 0110-41000 0100<- 1000 0011<- 1111 1100 #include<stdio.h> int main(){ char a = 128; char b = -129; char c = 300; unsigned char d = 300; /* 300-127=173 -128+172 */ printf("%d\n",d); /* 0111 1111 + 1 = 1000 0000 1000 0000 -1 = 0111 1111 */ return 0; }

计算类型的最大值

#include<stdio.h> int main(){ int a = 0; int b = a+1; while(a<b){ a++; b++; } printf("%d\n",a); return 0; }

最新回复(0)