音无结弦之时,天使跃动之心。立于浮华之世,奏响天籁之音。.|

次林梦叶

园龄:3年3个月粉丝:22关注:3

c语言拾遗

概述

gcc

-E 则经过预编译 变成.i文件,还是c代码只是对#中进行字符串的展开和复制

-S 则经过编译 变成 .s文件,为汇编代码

-c 则经过汇编 变成.o文件,为二进制文件

然后 将许多(也许也就几个).o文件链接在一起

生成linux中的可执行文件.out

直接gcc会将上述整个

如果要在编译停下来用 -E

如果要在汇编停下来用 -s

在链接时停下来用 -c

 

C语言编译链接过程通常包括四个部分:预处理、编译、汇编和链接。

  1. 预处理

预处理是指对源代码进行宏替换,头文件引入等预处理操作的过程。预处理器会将所有以 # 开头的指令进行处理(例如 #include、#define 等),并将结果输出到一个临时文件中。

可以使用以下命令进行预处理:gcc -E file.c -o file.i

  1. 编译

编译器将预处理后的文件转换为汇编代码。在这个阶段,编译器会检查代码语法和语义是否正确,并对代码进行优化。编译器将 C 代码转换为汇编语言代码,并将结果输出到一个目标文件中。

可以使用以下命令进行编译:gcc -S file.i -o file.s

  1. 汇编

汇编器将汇编代码转换为可重定位的二进制目标文件。它会将汇编代码转换为机器代码,并生成目标文件。目标文件包含了机器指令、符号表以及其他一些与目标文件相关的信息。

可以使用以下命令进行汇编:gcc -c file.s -o file.o

  1. 链接

链接器将多个目标文件合并为一个可执行文件。在这个阶段,链接器会解决全局符号的定义和引用关系,并把这些目标文件合并为一个可执行文件。

可以使用以下命令进行链接:gcc file.o -o executable

 

objdump 是用来查看一个二进制文件的反汇编

 

预编译

‘#’ 是预编译代码的标识

如:#include

#define

展开或代替

gcc a.c --verbose

 

 

如上我们甚至能在printf 中写 #include

但是我们知道 #include只是在寻找文件并复制,那么就很好理解了

 

 

在预编译的情况下,变量是不用通过定义即可使用的

除非变量被定义了,否则就为空

aa==bb为空,所以这里是输出Yes

 

还有#if 这是有判断的功能的

再来看看宏定义:

 

 

A 是 'aaaaaaaaaa'

TEN(xxx) 使用TEN(xxx),那么xxx会被重复十遍(按照上面代码写的)

那么B 就是十个'aaaaaaaaaa'

C是 十个 B

.........

巧妙利用宏还可以写出精炼的代码:

 

 

链接

 

 

将上面两个.c文件经过编译变成.o文件后,可以用gcc 将其链接

其实我们#include时都是看到的如:

 

 

的定义

其实最后都是经过链接才能真正使用的

 

加载

 

任何类型的指针其首先都是一个纯粹的保存地址的地方

所以任何一个指针其都可以赋值给void *

 

int * , float * ......

其首先都是一个纯粹的指针,前面的int等是对 这个指针指向的地方的解读

当其中的数据参与运算时,就按照 int /float ...类型进行运算

 

 

 

 

 

  main&main的值相同,是因为函数名本身就是一个指向函数入口地址的指针。

  注意这里main不是变量,也就是说没有花空间来保存main

  main === &main

  而argv&argv的值不同,则是因为它们代表的是不同的变量。argv是一个指向字符指针数组的指针,用于存储命令行参数。而&argvargv这个指针本身的地址,也就是说它存储的是argv指针变量在内存中的地址。

 

 

 

 

 

 

 

 

 

 

 

 

 

本文作者:次林梦叶

本文链接:https://www.cnblogs.com/cilinmengye/p/17299229.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   次林梦叶  阅读(25)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起