首页 > 其他分享 >C语言编译之分部编译

C语言编译之分部编译

时间:2023-07-03 19:47:10浏览次数:32  
标签:__ 文件 return C语言 编译 分部 源代码 hello

一、概述

在C语言中,将源代码转换为可执行文件的过程通常涉及以下几个步骤:

  1. 编写源代码:使用文本编辑器创建C语言源代码文件,通常以.c为扩展名。

  2. 预处理:使用预处理器对源代码进行处理。预处理器指令以#开头,用于包含头文件、宏定义等。预处理器会根据指令进行文本替换和宏展开等操作,生成经过预处理的代码。预处理的输出通常以.为扩展名。

  3. 编译:将预处理后的代码编译成汇编代码。编译器将C代码翻译成汇编语言,生成汇编代码文件。汇编代码是与特定硬件平台相关的低级代码。编译的输出通常以.s为扩展名。

  4. 汇编:使用汇编器将汇编代码转换为机器码目标文件。汇编器会将汇编代码转化为机器指令,并生成目标文件(二进制文件)。目标文件是以二进制格式表示的机器码文件。

  5. 链接:将目标文件与所需的库文件进行链接,生成可执行文件。链接器会将目标文件与系统库和用户自定义库文件进行合并,解析函数和符号引用,生成最终的可执行文件。

二、预处理

命令示例:gcc -E source.c -o source.i

在C语言中,预处理是在编译之前对源代码进行处理的一个阶段。预处理器根据预处理指令(以#开头)对源代码进行处理,并生成经过宏展开和文本替换的代码。以下是C语言中常见的预处理指令和功能:

1.包含头文件:使用#include指令将其他文件中的内容包含到当前文件中。这样可以在代码中使用其他文件中定义的函数、常量和宏等。

#include <stdio.h>

2.宏定义:使用#define指令定义宏,将代码中的标识符替换为指定的文本。宏可以用于简化代码、定义常量或实现条件编译等。

#include <stdio.h>
#define PI 3.14159 #define MAX(a, b) ((a) > (b) ? (a) : (b))
int main() { printf("Hello World %lf,%d\n", PI, MAX(10, 20)); return 0; }

.i文件中替换为

int main() {
 printf("Hello World %lf,%d\n", 3.14159, ((10) > (20) ? (10) : (20)));
 return 0;
}

3.条件编译:使用条件编译指令(#if#ifdef#ifndef#elif#else#endif)根据条件选择性地编译代码块。这允许根据不同的条件编译不同的代码。

#include <stdio.h>

int main() {
#if 0
    printf("Debugging mode enabled\n");
#else
    printf("Debugging mode disabled\n");
#endif    
    return 0;
}

.i文件中替换为

int main() {
 printf("Debugging mode disabled\n");
 return 0;
}

4.预处理不会检查语法错误

#include <stdio.h>

int main() {
    printf("Hello World")    
    return 0;
}
int main() {
    printf("Hello World")
    return 0;
}

5.预定义宏:C语言中有一些预定义的宏,提供关于编译环境和代码的信息。例如,__FILE__表示当前文件名,__LINE__表示当前行号。

#include <stdio.h>

int main() {
    printf("File: %s, Line: %d\n", __FILE__, __LINE__);    
    return 0;
}

.i文件中替换为

int main() {
    printf("File: %s, Line: %d\n", "hello.c", 4);
   return 0;
}

6.预处理文件中会将源代码文件中的注释删除

#include <stdio.h>

int main() {
    //printf("File: %s, Line: %d\n", __FILE__, __LINE__);
   return 0;
}
int main() {
 return 0;
}

三、编译

示例命令:gcc -S source.i -o source.s

将预处理文件编译成汇编文件,另外也会检查语法错误

四、汇编

示例命令:gcc -c source.s -o source.o

将汇编文件编译成二进制文件.o

五、链接

示例命令:gcc source.o -o executable

将二进制文件链接成可执行文件

六、总结

使用GCC编译器可以将C语言源代码文件编译为可执行文件。以下是使用GCC编译C文件的基本命令格式:

gcc source.c -o executable

其中,source.c是C语言源代码文件的名称,executable是生成的可执行文件的名称。你可以根据需要将这些名称替换为实际的文件名。

例如,假设你有一个名为hello.c的源代码文件,可以使用以下命令将其编译为可执行文件hello

gcc hello.c -o hello

在执行此命令后,GCC将对hello.c进行编译,并生成一个名为hello的可执行文件。

除了基本的编译命令外,你还可以使用GCC的选项来进行更高级的编译设置,例如指定优化级别、调试信息等。以下是一些常用的GCC选项示例:

指定优化级别为-O2

gcc hello.c -o hello -O2

添加调试信息-g

gcc hello.c -o hello -g

输出详细的警告信息-Wall

gcc hello.c -o hello -Wall

指定需要链接的库文件:

gcc hello.c -o hello -lm

上述命令中的-lm选项用于链接数学库(libm)。

标签:__,文件,return,C语言,编译,分部,源代码,hello
From: https://www.cnblogs.com/TechNomad/p/17523803.html

相关文章

  • C语言运算符优先级
    在C语言中,运算符优先级是一个比较麻烦的概念,如果搞不清楚优先级可能会产生一些难以察觉的错误第一优先级:[]().->第一优先级包括方括号,圆括号,对象,对象指针第二优先级:-~++–*&!(类型)sizeof第二优先级包括取负,按位取反,自增,自减,取值运算符,取地址符,逻辑非运算符,强制......
  • C语言(2)
    目录6.数组6.1数组的概念6.2一维数组6.3排序问题6.3.1插入排序6.3.2冒泡排序6.3.3选择排序6.4二分查找6.5字符数组6.6二维数组6.数组6.1数组的概念一组具有相同类型,相同含义的数据类型的有序集合。数组不是基本类型,是构造类型。数组的本质/数组的存储方式:一片地址连续的空间......
  • C语言(1)
    目录1.数据类型1.1基本类型1.2构造类型1.3指针类型1.4空类型(void)2.变量和常量2.1C语言中常量的表示方式2.2数据在内存中的存储2.3C语言中变量的表示方式2.3.1变量的定义2.3.2变量的含义3.整数之间的赋值问题3.1长的赋值给短的3.2短的赋值给长的4.运算符与表达式4.1运算符的分类4.2......
  • C语言(二)
    目录6.数组6.1数组的概念6.2一维数组6.3排序问题6.3.1插入排序6.3.2冒泡排序6.3.3选择排序6.4二分查找6.5字符数组6.6二维数组6.数组6.1数组的概念一组具有相同类型,相同含义的数据类型的有序集合。数组不是基本类型,是构造类型。数组的本质/数组的存储方式:一片地址连续的空间......
  • 记一次编译错误
    我在照着STL源码刨析写STL的时候出现了一个编译错误.当时的情况是我要用一个派生类的指针给一个基类指针的引用赋值,类似于:classBase{};classDerived:publicBase{};Derived*d=newDerived();Base*&b=d;但是编译器报错,错误信息类似于:error:cannotb......
  • [oeasy]python0070_动态类型_静态类型_编译_运行_匈牙利命名法
     动态类型_静态类型回忆上次内容 上次了解了帮助文档的生成开头的三引号注释可以生成帮助文档文档可以写成网页 python3本身也有在线的帮助手册 目前的程序提高了可读性   ​ 添加图片注释,不超......
  • [oeasy]python0070_动态类型_静态类型_编译_运行_匈牙利命名法
    动态类型_静态类型回忆上次内容上次了解了帮助文档的生成开头的三引号注释可以生成帮助文档文档可以写成网页python3本身也有在线的帮助手册目前的程序提高了可读性还有什么方法可以让程序更可读么?......
  • C++面试八股文:std::array如何实现编译器排序?
    C++面试八股文:std::array如何实现编译器排序?某日二师兄参加XXX科技公司的C++工程师开发岗位第25面:面试官:array熟悉吗?二师兄:你说的是原生数组还是std::array?面试官:你觉得两者有什么区别?二师兄:区别不是很大,原生数组(非动态数组)和std::array都在栈上开辟空间,初始化的时候......
  • 龙蜥7.9 编译安装redis
    1、下载redis安装包2、我一般放在/home下面,redis默认安装在/usr/local/bin/下面,修改目录命令为:makePREFIX=/usr/local/redisinstall#安装编译环境yum-yinstallgcc-c++autoconfautomake#开始安装cd/hometarzxvfredis-7.0.11.tar.gzcdredis-7.0.11/makemakeinsta......
  • C语言
    目录1.数据类型1.1基本类型1.2构造类型1.3指针类型1.4空类型(void)2.变量和常量2.1C语言中常量的表示方式2.2数据在内存中的存储2.3C语言中变量的表示方式2.3.1变量的定义2.3.2变量的含义3.整数之间的赋值问题3.1长的赋值给短的3.2短的赋值给长的4.运算符与表达式4.1运算符的分类4.2......