我学C的那些年[ch01]:浅淡C语言的编译过程

时间:2022-02-12 06:27:42

前几天大致学习了C语言的编译过程,那么今天就和大家分享一下

首先,编译C语言,需要一个文本编辑器(windows自带的也行),和一个MinGW编译器(需要配置环境),就可以将.c文件编译成.exe文件.

现在, 我将演示一个简单的案例:

新建一个txt文件,改后缀名为c

我学C的那些年[ch01]:浅淡C语言的编译过程

然后打开编辑代码为:

#include <stdio.h>

void main(){
printf("Hellow World");
}

打开dos命令,通过cd命令 “first.c文件的目录”,我的first.c文件的

绝对路径C:\Users\Zero\Desktop\c\process\first.c

到达文件的目录后 ,

执行gcc first.c –o firstFile.exe,即可编译成功 ,输入firstFile.exe运行该程序

我学C的那些年[ch01]:浅淡C语言的编译过程

这样就编译好了一个简单的c文件.

上面,我们看到,我用了gcc first.c –o firstFile.exe 编译c文件, 其中的first.c就是需要编译的c文件,-o就是生成目标文件(即first.c被编译后的文件) , firstFile.exe就是生成文件的名称.

下面我会大致的讲一下gcc的命令,  和c的编译过程

常用gcc选项的含义(区分大小写):

-c 编译为目标文件
-E 只进行预处理
-o 设定生成的文件

c语言的编译过程可以分为4个阶段:

  1. 预处理:加载预处理文件,对源程序的替换工作
  2. 编译:检查语法错误,将代码编译成汇编文件
  3. 汇编:把汇编语言代码翻译成目标机器指令的过程
  4. 链接:将各个模块之间相互引用的部分处理好,使得各个模块之间能够正确地衔接

c语言的编译过程流程图:

我学C的那些年[ch01]:浅淡C语言的编译过程

下面我将写一些例子,了解一下这4个部分,以及一些gcc命令:

1.预处理

创建文件:preProcessing.c

绝对路径C:\Users\Zero\Desktop\c\process\preProcessing.c

#include <stdio.h>
#define PI 3.1415926 //定义PI常量void main(){
printf("PI的值:%f",PI);
}

执行预处理:

我学C的那些年[ch01]:浅淡C语言的编译过程

将preProcessing.c进行预处理后,生成p.i文件,这个时候我们可以用文本方法打开p.i文件,查看它加载了什么内容,以及替换:

不过,将预处理的内容和原来写的代码放在一起,内容也是很多的,末尾还是能找到自己写的代码的.

#  "preProcessing.c"
# "<command-line>"
# "preProcessing.c"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h" # "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\_mingw.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\_mingw.h" # "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\_mingw.h" # "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sdkddkver.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sdkddkver.h" # "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sdkddkver.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\_mingw.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\_mingw.h"
struct threadlocalinfostruct;
struct threadmbinfostruct;
typedef struct threadlocalinfostruct *pthreadlocinfo;
typedef struct threadmbcinfostruct *pthreadmbcinfo; typedef struct localeinfo_struct {
pthreadlocinfo locinfo;
pthreadmbcinfo mbcinfo;
} _locale_tstruct, *_locale_t;
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h" # "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\lib\\gcc\\mingw32\\4.8.1\\include\\stddef.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\lib\\gcc\\mingw32\\4.8.1\\include\\stddef.h"
typedef unsigned int size_t;
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\lib\\gcc\\mingw32\\4.8.1\\include\\stddef.h"
typedef short unsigned int wchar_t;
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\lib\\gcc\\mingw32\\4.8.1\\include\\stddef.h"
typedef short unsigned int wint_t;
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h" # "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\lib\\gcc\\mingw32\\4.8.1\\include\\stdarg.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\lib\\gcc\\mingw32\\4.8.1\\include\\stdarg.h"
typedef __builtin_va_list __gnuc_va_list;
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE; extern __attribute__ ((__dllimport__)) FILE _iob[];
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fopen (const char*, const char*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) freopen (const char*, const char*, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fflush (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fclose (FILE*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) remove (const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rename (const char*, const char*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) tmpfile (void);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) tmpnam (char*); char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _tempnam (const char*, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _rmtmp(void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _unlink (const char*); char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) tempnam (const char*, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rmtmp(void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) unlink (const char*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) setvbuf (FILE*, char*, int, size_t); void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) setbuf (FILE*, char*);
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_fprintf(FILE*, const char*, ...);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_printf(const char*, ...);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_sprintf(char*, const char*, ...);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_snprintf(char*, size_t, const char*, ...);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vfprintf(FILE*, const char*, __gnuc_va_list);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vprintf(const char*, __gnuc_va_list);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vsprintf(char*, const char*, __gnuc_va_list);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vsnprintf(char*, size_t, const char*, __gnuc_va_list);
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fprintf (FILE*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) printf (const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) sprintf (char*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfprintf (FILE*, const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vprintf (const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsprintf (char*, const char*, __gnuc_va_list);
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_fprintf(FILE*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_printf(const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_sprintf(char*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_vfprintf(FILE*, const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_vprintf(const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_vsprintf(char*, const char*, __gnuc_va_list); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _snprintf (char*, size_t, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vsnprintf (char*, size_t, const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vscprintf (const char*, __gnuc_va_list);
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) snprintf (char *, size_t, const char *, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsnprintf (char *, size_t, const char *, __gnuc_va_list); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vscanf (const char * __restrict__, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfscanf (FILE * __restrict__, const char * __restrict__,
__gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsscanf (const char * __restrict__,
const char * __restrict__, __gnuc_va_list); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fscanf (FILE*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) scanf (const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) sscanf (const char*, const char*, ...); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetc (FILE*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgets (char*, int, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputc (int, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputs (const char*, FILE*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) gets (char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) puts (const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ungetc (int, FILE*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _filbuf (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _flsbuf (int, FILE*); extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getc (FILE*);
extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getc (FILE* __F)
{
return (--__F->_cnt >= )
? (int) (unsigned char) *__F->_ptr++
: _filbuf (__F);
} extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putc (int, FILE*);
extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putc (int __c, FILE* __F)
{
return (--__F->_cnt >= )
? (int) (unsigned char) (*__F->_ptr++ = (char)__c)
: _flsbuf (__c, __F);
} extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getchar (void);
extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getchar (void)
{
return (--(&_iob[])->_cnt >= )
? (int) (unsigned char) *(&_iob[])->_ptr++
: _filbuf ((&_iob[]));
} extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putchar(int);
extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putchar(int __c)
{
return (--(&_iob[])->_cnt >= )
? (int) (unsigned char) (*(&_iob[])->_ptr++ = (char)__c)
: _flsbuf (__c, (&_iob[]));}
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fread (void*, size_t, size_t, FILE*);
size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fwrite (const void*, size_t, size_t, FILE*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fseek (FILE*, long, int);
long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ftell (FILE*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rewind (FILE*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fseek_nolock (FILE*, long, int);
long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ftell_nolock (FILE*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fseeki64 (FILE*, long long, int);
long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ftelli64 (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fseeki64_nolock (FILE*, long long, int);
long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ftelli64_nolock (FILE*);
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
typedef long long fpos_t; int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetpos (FILE*, fpos_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fsetpos (FILE*, const fpos_t*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) feof (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ferror (FILE*);
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) clearerr (FILE*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) perror (const char*); FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _popen (const char*, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _pclose (FILE*); FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) popen (const char*, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) pclose (FILE*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _flushall (void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fgetchar (void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fputchar (int);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fdopen (int, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fileno (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fcloseall (void);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fsopen (const char*, const char*, int);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _getmaxstdio (void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _setmaxstdio (int);
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetchar (void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputchar (int);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fdopen (int, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fileno (FILE*);
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sys\\types.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sys\\types.h" # "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sys\\types.h" # "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\lib\\gcc\\mingw32\\4.8.1\\include\\stddef.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\lib\\gcc\\mingw32\\4.8.1\\include\\stddef.h"
typedef int ptrdiff_t;
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sys\\types.h"
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sys\\types.h"
typedef long __time32_t; typedef long long __time64_t;
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sys\\types.h"
typedef __time64_t time_t; typedef long _off_t; typedef _off_t off_t; typedef long long _off64_t; typedef long long off64_t; typedef unsigned int _dev_t; typedef _dev_t dev_t; typedef short _ino_t; typedef _ino_t ino_t; typedef int _pid_t; typedef _pid_t pid_t; typedef unsigned short _mode_t; typedef _mode_t mode_t; typedef int _sigset_t; typedef _sigset_t sigset_t; typedef int _ssize_t; typedef _ssize_t ssize_t; typedef long long fpos64_t;
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\sys\\types.h"
typedef unsigned int useconds_t;
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
extern __inline__ FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fopen64 (const char*, const char*);
extern __inline__ FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fopen64 (const char* filename, const char* mode)
{
return fopen (filename, mode);
} int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fseeko64 (FILE*, off64_t, int); extern __inline__ off64_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ftello64 (FILE *);
extern __inline__ off64_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ftello64 (FILE * stream)
{
fpos_t pos;
if (fgetpos(stream, &pos))
return -1LL;
else
return ((off64_t) pos);
}
# "c:\\users\\zero\\desktop\\mytools\\mingw 4.8.1\\mingw32\\include\\stdio.h"
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fwprintf (FILE*, const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wprintf (const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _snwprintf (wchar_t*, size_t, const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfwprintf (FILE*, const wchar_t*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vwprintf (const wchar_t*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vsnwprintf (wchar_t*, size_t, const wchar_t*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vscwprintf (const wchar_t*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fwscanf (FILE*, const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wscanf (const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) swscanf (const wchar_t*, const wchar_t*, ...);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetwc (FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputwc (wchar_t, FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ungetwc (wchar_t, FILE*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) swprintf (wchar_t*, const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswprintf (wchar_t*, const wchar_t*, __gnuc_va_list); wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetws (wchar_t*, int, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputws (const wchar_t*, FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getwc (FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getwchar (void);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putwc (wint_t, FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putwchar (wint_t); void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _lock_file(FILE*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _unlock_file(FILE*);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _getws (wchar_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _putws (const wchar_t*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfdopen(int, const wchar_t *);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfopen (const wchar_t*, const wchar_t*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfreopen (const wchar_t*, const wchar_t*, FILE*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfsopen (const wchar_t*, const wchar_t*, int);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtmpnam (wchar_t*);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtempnam (const wchar_t*, const wchar_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wrename (const wchar_t*, const wchar_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wremove (const wchar_t*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wperror (const wchar_t*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wpopen (const wchar_t*, const wchar_t*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) snwprintf (wchar_t* s, size_t n, const wchar_t* format, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, __gnuc_va_list arg); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vwscanf (const wchar_t * __restrict__, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfwscanf (FILE * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (const wchar_t * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list); FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wpopen (const wchar_t*, const wchar_t*); wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fgetwchar (void);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fputwchar (wint_t);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _getw (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _putw (int, FILE*); wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetwchar (void);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputwchar (wint_t);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getw (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putw (int, FILE*);
# "preProcessing.c" void main(){
printf("PI的值:%f",3.1415926);
}

加载头文件后,代码就是这样了,  以及我们看到main函数中, 原来的常量PI不见了,被3.1415926替换掉了.

预处理:主要处理#include预编译指令和替换系相关的代码

2.编译

源文件:preProcessing.c

绝对路径C:\Users\Zero\Desktop\c\process\preProcessing.c

#include <stdio.h>
#define PI 3.1415926 //定义PI常量void main(){
printf("PI的值:%f",PI);
}

这里需要用到gcc另外的一个选项:

-S 把预处理完的文件进行语法分析,生成汇编代码

执行编译:

我学C的那些年[ch01]:浅淡C语言的编译过程

也可以打开p2.s,来查看一下:

.file    "preProcessing.c"
.def ___main; .scl ; .type ; .endef
.section .rdata,"dr"
LC1:
.ascii "PI\265\304\326\265:%f\0"
.text
.globl _main
.def _main; .scl ; .type ; .endef
_main:
LFB6:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset
.cfi_offset , -
movl %esp, %ebp
.cfi_def_cfa_register
andl $-, %esp
subl $, %esp
call ___main
fldl LC0
fstpl (%esp)
movl $LC1, (%esp)
call _printf
leave
.cfi_restore
.cfi_def_cfa ,
ret
.cfi_endproc
LFE6:
.section .rdata,"dr"
.align
LC0:
.long
.long
.ident "GCC: (GNU) 4.8.1"
.def _printf; .scl ; .type ; .endef

不过,我并没有看出来什么罢了,当然,没看出来也无所谓.

-S:还是会对代码进行语法分析的,不过,刚刚并没有看出来,我们可以尝试修改下代码,看看是否报错

#include <stdio.h>
#define PI 3.1415926 //定义PI常量
void main(){
sdf;
printf("PI的值:%f",PI);
}

再次执行编译:

我学C的那些年[ch01]:浅淡C语言的编译过程

这次果然报错了,控制台报error:sdf没有声明, 当然这里 预处理 是没有报错的,编译报错了.

如果你在上面改不是”sdf;”, 而是”sdf();”,我想编译的阶段就不会报错了,至于为什么,看了第四个阶段链接,你也许就明白了.

#include <stdio.h>
#define PI 3.1415926 //定义一个PI常量 void main(){
sdf();
printf("PI的值:%f",PI);
}

执行编译:

我学C的那些年[ch01]:浅淡C语言的编译过程

3.汇编

在这里,我需要用到另外一个指令,不是gcc指令的选项,

as 将汇编代码转化成机器能读懂的指令,生成目标文件

源文件:preProcessing.c

绝对路径C:\Users\Zero\Desktop\c\process\preProcessing.c

#include <stdio.h>
#define PI 3.1415926 //定义一个PI常量 void main(){
printf("PI的值:%f",PI);
}

执行汇编:

我学C的那些年[ch01]:浅淡C语言的编译过程

为了看到效果,我准备也打开p3.o文件,查看一下,不过,生成的是机器码,可能有些文本编辑器打开会乱码,这里我用的是Sublime Text编辑器打开查看:

4c01    c201
2e74 2e64 30c0 2e62 30c0 2e72 2c01
2f34 2f31 b801
e583 e4f0 83ec 10e8
dd05 dd5c c704
00e8 c9c3 b5c4
d6b5 3a25 4ad8 124d
fb21 433a 474e
2e38 2e31
017a 017c 1b0c
1c00 1c00
0e08 420d c50c
0a00 0f00
1b00 2e66 696c feff
726f 696e
672e 5f6d 6e00
2e74 2e64 2e62 2e72 5f5f 5f6d 6e00 5f70 6e74
2e00 2e72
247a 7a7a 002e 5f66 6d65 002e
7a7a 7a00 2e65 685f
616d

汇编就是将汇编代码转变成机器可以执行的命令

4.链接

链接的话,首先,你要明白自定义头文件,以及使用它.

这里创建的文件都在”C:\Users\Zero\Desktop\c\process\”目录下

创建main.c文件:

#include <stdio.h>

int sum(int x,int y){
return x+y;
} void main(){
int a=;
int b=;
int result; result=sum(a,b); printf("result:%d",result);
}

这里简单的定义了一个sum函数,现在,sum函数的我不想放在main.c文件中,

把sum函数放入头文件中:

1.创建一个headFile.h头文件,也就是后缀名为h的文件:

int sum(int x,int y);

头文件中有函数的声明,但不需要函数的定义.

2.修改main.c文件:

#include <stdio.h>
#include "headFile.h"; void main(){
int a=;
int b=;
int result; result=sum(a,b); printf("result:%d",result);
}

3.这个时候,还缺少sum函数的定义,再创建sum.c文件:

int sum(int x,int y){
return x+y;
}

最前面我开始编译first.c文件,直接用了gcc指令(没有加选项的) , 将c文件直接变成exe文件,

是直接完成预处理,编译,汇编,链接这四个阶段.

那么,现在为了方便,就不用一个阶段,一个阶段执行过来.直接使用gcc

对main.c文件,和sum.c文件进行一起编译:

我学C的那些年[ch01]:浅淡C语言的编译过程

至于我为什么要两个文件一起编译,这个可以看我原来写的main.c文件,headFile.h文件,sum.c文件,

假如我只编译main.c文件, main.c文件导入headFile.h文件,但是headFile.h里面只有sum函数的声明,却没有sum函数的实现(定义), 它怎么会知道这个函数是做什么事情?, 所以这个时候,需要和 sum.c文件一起编译,sum.c文件里面有sum函数的实现.

链接: 顾名思义就是将相关的东西链接起来, 函数也是其中一种.

这个时候,你就可以去思考,为什么当时编译阶段的时候(gcc –S ), “sdf()”函数不报错的原因,因为前面三个阶段都不会去检查相关链接信息.我们也可以感受一下:

前面我也说过gcc的常用的选项 ,其中有一个选项是”-c”, 可以将C文件 直接 编译成 目标文件,

也是就从 后缀名c 编译成 后缀名o  -> 直接完成预处理,编译,汇编 这三个阶段,

就用刚刚的那三个文件main.c,headFile.h,sum.c

分开执行前三个阶段:

我学C的那些年[ch01]:浅淡C语言的编译过程

我们发现main.c和sum.c两个文件单独执行前三个阶段都不会出错,

现在,单独执行main.c文件,把它变成exe文件:

我学C的那些年[ch01]:浅淡C语言的编译过程

这个时候,控制台说:没有定义sum函数的引用,然后就出现error了, 说明:这个时候,它才去检查sum函数定义,

编译阶段(gcc –S)的时候,并没有检查sum函数,语法没问题的话,就可以通过编译阶段了.

最后, m.o 和 s.o 还是可以一起编译成功的:

我学C的那些年[ch01]:浅淡C语言的编译过程

一般头文件里的函数: 都会编译成  *.o  文件:

1.可以加快编译的速度,

2.可以对函数进行一个封装, 将*.o文件交给别人,别人并不知道其中的实现代码

3.最好, 再写个帮助文档什么的,说明其函数的作用

基本上,我也把编译过程大致的写了一下,可以再看看c语言的编译流程图什么的,不过,

还有很多细节方面,我也就不去写了,大概的意思明白了的话,

其他的细节再看看,就会明白的,不明白的话就继续摆渡吧!