我是靠谱客的博主 淡淡可乐,最近开发中收集的这篇文章主要介绍C-1 入门知识,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

笔者在WIN10VC6.0下学习的笔记。

标题

      • 编译
        • 预处理
        • 编译和汇编
        • 链接

编译

VC安装目录C:Program Files (x86)Microsoft Visual StudioVC98Bin中就是IDE编译套件。
目录文件信息如下:

cl.exe
link.exe
c1.dll
c2.dll
c1xx.dll

其中cl为编译器(command line),其实现位于c1.dll c2.dll c1.dll.而link.exe 便是链接工具.

首先一个最简单的hello.cpp如下:

#include <stdio.h>
void main(){
	printf("bb");
	printf("aa");
}

编译的步骤大致分为四步骤:
1.预编译
2.编译
3.汇编
4.链接

关于这几步网上到处是轮子,详情请参阅:c编译流程

我们在vc提供的编译套件中手动实现这几步。

预处理

cl /p hello.cpp 预编译会将include展开放入生成的hello.i文件中.(关于更多编译选项 可输入 cl -help查看或c编译选项)

#line 1 "Cpp1.cpp"
#line 1 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"


 int __cdecl _fileno(FILE *);
#line 307 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"

 int __cdecl _flushall(void);
 FILE * __cdecl fopen(const char *, const char *);
 int __cdecl fprintf(FILE *, const char *, ...);
 int __cdecl fputc(int, FILE *);
 int __cdecl _fputchar(int);
 int __cdecl fputs(const char *, FILE *);
 size_t __cdecl fread(void *, size_t, size_t, FILE *);
 FILE * __cdecl freopen(const char *, const char *, FILE *);
 int __cdecl fscanf(FILE *, const char *, ...);
 int __cdecl fsetpos(FILE *, const fpos_t *);
 int __cdecl fseek(FILE *, long, int);
 long __cdecl ftell(FILE *);
 size_t __cdecl fwrite(const void *, size_t, size_t, FILE *);
 int __cdecl getc(FILE *);
 int __cdecl getchar(void);
 int __cdecl _getmaxstdio(void);
 char * __cdecl gets(char *);
 int __cdecl _getw(FILE *);
 void __cdecl perror(const char *);
 int __cdecl _pclose(FILE *);
 FILE * __cdecl _popen(const char *, const char *);
 int __cdecl printf(const char *, ...);
 int __cdecl putc(int, FILE *);
 int __cdecl putchar(int);
 int __cdecl puts(const char *);
 int __cdecl _putw(int, FILE *);
 int __cdecl remove(const char *);
 int __cdecl rename(const char *, const char *);
 void __cdecl rewind(FILE *);
 int __cdecl _rmtmp(void);
 int __cdecl scanf(const char *, ...);
 void __cdecl setbuf(FILE *, char *);
 int __cdecl _setmaxstdio(int);
 int __cdecl setvbuf(FILE *, char *, int, size_t);
 int __cdecl _snprintf(char *, size_t, const char *, ...);
 int __cdecl sprintf(char *, const char *, ...);
 int __cdecl sscanf(const char *, const char *, ...);
 char * __cdecl _tempnam(const char *, const char *);
 FILE * __cdecl tmpfile(void);
 char * __cdecl tmpnam(char *);
 int __cdecl ungetc(int, FILE *);
 int __cdecl _unlink(const char *);
 int __cdecl vfprintf(FILE *, const char *, va_list);
 int __cdecl vprintf(const char *, va_list);
 int __cdecl _vsnprintf(char *, size_t, const char *, va_list);
 int __cdecl vsprintf(char *, const char *, va_list);


#line 363 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"




 FILE * __cdecl _wfsopen(const wchar_t *, const wchar_t *, int);
#line 369 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"

 wint_t __cdecl fgetwc(FILE *);
 wint_t __cdecl _fgetwchar(void);
 wint_t __cdecl fputwc(wint_t, FILE *);
 wint_t __cdecl _fputwchar(wint_t);
 wint_t __cdecl getwc(FILE *);
 wint_t __cdecl getwchar(void);
 wint_t __cdecl putwc(wint_t, FILE *);
 wint_t __cdecl putwchar(wint_t);
 wint_t __cdecl ungetwc(wint_t, FILE *);

 wchar_t * __cdecl fgetws(wchar_t *, int, FILE *);
 int __cdecl fputws(const wchar_t *, FILE *);
 wchar_t * __cdecl _getws(wchar_t *);
 int __cdecl _putws(const wchar_t *);

 int __cdecl fwprintf(FILE *, const wchar_t *, ...);
 int __cdecl wprintf(const wchar_t *, ...);
 int __cdecl _snwprintf(wchar_t *, size_t, const wchar_t *, ...);
 int __cdecl swprintf(wchar_t *, const wchar_t *, ...);
 int __cdecl vfwprintf(FILE *, const wchar_t *, va_list);
 int __cdecl vwprintf(const wchar_t *, va_list);
 int __cdecl _vsnwprintf(wchar_t *, size_t, const wchar_t *, va_list);
 int __cdecl vswprintf(wchar_t *, const wchar_t *, va_list);
 int __cdecl fwscanf(FILE *, const wchar_t *, ...);
 int __cdecl swscanf(const wchar_t *, const wchar_t *, ...);
 int __cdecl wscanf(const wchar_t *, ...);


 FILE * __cdecl _wfdopen(int, const wchar_t *);
 FILE * __cdecl _wfopen(const wchar_t *, const wchar_t *);
 FILE * __cdecl _wfreopen(const wchar_t *, const wchar_t *, FILE *);
 void __cdecl _wperror(const wchar_t *);
 FILE * __cdecl _wpopen(const wchar_t *, const wchar_t *);
 int __cdecl _wremove(const wchar_t *);
 wchar_t * __cdecl _wtempnam(const wchar_t *, const wchar_t *);
 wchar_t * __cdecl _wtmpnam(wchar_t *);



#line 414 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"
#line 415 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"


#line 418 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"





//省略一大批



 int __cdecl fcloseall(void);
 FILE * __cdecl fdopen(int, const char *);
 int __cdecl fgetchar(void);
 int __cdecl fileno(FILE *);
 int __cdecl flushall(void);
 int __cdecl fputchar(int);
 int __cdecl getw(FILE *);
 int __cdecl putw(int, FILE *);
 int __cdecl rmtmp(void);
 char * __cdecl tempnam(const char *, const char *);
 int __cdecl unlink(const char *);

#line 463 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"


}
#line 467 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"


#pragma pack(pop)
#line 471 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"

#line 473 "C:\Program Files (x86)\Microsoft Visual Studio\VC98\include\stdio.h"
#line 2 "hello.cpp"
void main(){
	printf("bb");
	printf("aa");

}

第一个问题,我们的include<stdio.h>会首先去环境变量的include寻找的对应的头文件,如果没有找到那么将去编译目录 也就是hello.cpp本文件所在目录寻找stdio.h

笔者所在电脑的include环境变量:

C:Program Files (x86)Microsoft Visual StudioVC98atlinclude;
C:Program Files (x86)Microsoft Visual StudioVC98mfcinclude;
C:Program Files (x86)Microsoft Visual StudioVC98include

如果开发者用双引号寻找头文件(include "")那么首先会去编译目录 helllo.cpp寻找,如果找不到才会寻找环境变量include

另外可以在预编译的文件中可以看到导入的头文件具体位置。

编译和汇编

笔者并没有在vc编译选项中找到,所以我就干脆把这两步骤合为一步。

cl c hello.i 其中c选项为编译但是不连接,hello.i 是预处理后的文件.
运行后目录将生成一个 二进制hello.obj文件,此文件可以用winhex查看。

链接

c语言要运行必须链接实现的实现库,比如我们的include<stdio.h>printl函数,只是在预处理的时候导入的声明然而具体的实现其没有,所以我们必须借助link.exe链接并生成可执行文件。

我们查看msdn文档的printf函数,了解到printf 实现库存在三个库中,分别为LIBC,LIBCMT,MSVCRT,分别对应单线程, 多线程,Microsoft visual C RUN TIME版本实现,我们这里只需要单线程版本。
在这里插入图片描述

所以 我们键入如下命令link hello.obj LIBC.LIB完成最终的程序并生成Hello.exe

最后

以上就是淡淡可乐为你收集整理的C-1 入门知识的全部内容,希望文章能够帮你解决C-1 入门知识所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部