您的位置:首页 > 编程语言 > C语言/C++

还是C语言

2013-12-22 18:14 162 查看
还是C语言

首先说c语言的编译环境包括,翻译环境和执行环境,所谓的编译环境是,将程序翻译成

指令格式,所谓的执行环境这就是标准说明在一台机器上运行,这就牵扯到所谓的操作系统

交叉编译器。

关于程序编译,编译出来的.i文件就是编译器翻译展开的文件

1.条件编译

#include<stdio.h>

#define C 1

int main()

{

#if(1==C)

printf("printf 1 print ");

#else

printf("printf 2 print ");

#endif

return 0;

}



#include<stdio.h>

#define C 1

int main()

{

if(1==C)

printf("printf 1 print ");

else

printf("printf 2 print ");

return 0;

}

二者的结果相同,但是而这个程序可以通过gcc

生成.i文件可以发现前者就是简单的替换,

后者则是需要判断之后再执行

二者预编译结果显示,这下面值显示main函数部分,对于都文件不显示

对于程序1是:

main()

{

printf("printf 1 print ");

return 0;

}

程序2:

main()

{

if(1==1)

printf("printf 1 print ");

else

printf("printf 2 print ");

return 0;

}

感想:在这个程序的编译过程中我们可以发现一个问题就是宏定义,我们不需要修改代码页

可以在命令中实现,

@root  gcc -E -DC==1/*宏定义*/ -o 生成文件名.i 即可编译完成;

2.关于头文件。

在头文件中出现几次调用的情况。

比如:在同一个文件之中包含以下几个文件

test.c

#include <stdio.h>

#include "test.h"

#include "test.h"

#include "head.h"

#include "head.h"

int main()

{

f();

printf("%s\n",name);

return 0;

}

test.h

#ifndef  TEST_H

#define TEST_H

#include <stdio.h>

#include  "head.h"

const char name="hello word";

void f()

{

printf("%s",name);

}

head.h

#ifndef HEAD_H

#define HEAD_H

int head =1;

#endif

假如不适用条件编译在调用test.c时会报错,有重定义发生,但是只要

我们使用条件编译,头文件可以无限包含

这就是在linux内核中为什么可以头文件可以包含多个原因

3.关于error和warning的使用

介绍一般#error message是给程序员特意的编译错误消息,

类似的 #warning 一般都会回产生错误但是不会提示警告:

#include<stdio.h>

#define CON_1 "CON_1"

#define CON_2 "CON_2"

int main()

{

#ifndef COMM

#warning Compling will be stoped

#error No define Constant symbol

#endif

printf("%s\n",COMM);

printf("%s",CON_1);

printf("%s",CON_2);

return 0;

}

此处定义的宏是COMM程序在执行过程之中

会检测假如程序未定义COMM的话会程序会产生警告和错误并且终止。

条件测试的出现未产品的测试和发布都提供了很好地技术支持;

4.#line 用于强制指定新的行号和编译文件名

并对源文件的代码重新编号。

#line number filename (filename可以省略)

#include <stdio.h>

#line 14 "sxp.c"

#define CON_1 "CON_1"

#define CON_2 "CON_2"

void f()

{

return 0;

}

int main()

{

printf("%s\n",CON_1);

printf("%s\n".CON_2);

printf("%d",_LINE_);//编译器自带的宏定义

printf("%s\n",_FILE_);//同上

f();

return 0;

}

例子中的#LINE的宏定义表示在这个宏定义的下一行是14行。。

c库中引入的line的意义就是程序的无关性,一般就是指定

自己的代码段用于调试使用

5.#pragma是编译器指示字,用于编译器完成特定的动作

编译器和操作系统特有,不可在不同编译器之间移植

#pragma parameter 

#pragma message 输出编译的消息

例子:

注:vc中有message,在linux 中的gcc将其忽略

#include <stdio.h>

#if defined (ANDROID20)

#pragma message (" complie android ...");

#define VERSION "Android 2.0"

#elseif defined(ANDROID23)

#pragma message (" complie android 23...");

#define VERSION "Android 2.3"

#else

#error compline versin is not proved!

int main()

{

printf("$s",VERSION);

return 0;

}

#pragma pack

内存对齐,不同的数据在内存中按照一定的顺序排放,不是顺寻的

一个挨着一个排放。

pragma pack这个关键字可以指定cpu的内存编译器对齐的方式

例子:

#pragma pack(2)

{

char c;

short s;

}

以2个字节读写,

这个struct的大小是:

#pragma pack(4)

{

char c;

short s;

}

以4个字节读写,

这个关键字可以排除编译器的硬件异常情况发生

6.关于cpu读写字节,一般是按照2^n读写的。

列子:struct T

{

char c;

short s;

}

这个例子中char占用一个字节,short占有2字节,所以一共是三个字节

但是cpu会把其当作4个字节读取,写入;

7.关于#与##运算符运算符

#include<stdio.h>

#define NAME(n) name##n

int main()

{

int NAME(1);

int NAME(2);

NAME(1)=1;

NAME(2)=2;

printf("%d\n%d\n",NAME(1),NAME(2));

return 0;

}

巧妙运用:

#include<stdio.h>

#define STRUCT(type) typedef struct _tag_##type type;\

struct _tag_##type

STRUCT(Stucdent)

{

char *name;

int id;

}

int main()

{

Stucdent s1;

Stucdent s2;

s1.name="s1";

s1.id=0;

s2.name="s2";

s2.id=1;

printf("%s\n",s1.name);

printf("%d\n",s1.id);

printf("%s\n",s2.name);

printf("%d\n",s2.id);

return 0;

}

翻译之后的是

typedef struct _tag_Student Student;struct _tag_Student{

char *name;

int id;

};

............

注:利用gcc 命令生成.i文件。查看最后源代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: