0
点赞
收藏
分享

微信扫一扫

环境和预处理

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h>

#include<stddef.h> //程序的翻译环境 //程序的执行环境 //详解:C语言程序的编译+链接 //预定义符号介绍 //预处理指令#define //宏和函数对比 //预处理操作符#和##的介绍 //命令定义 //预处理指令#include //预处理指令#undef //条件编译 //test.c如何变成test.exe //程序编译的翻译环境(编译,链接)和执行环境 //编译(预编译,编译,汇编) //编译是把多个源文件都单独进行编译器的编译,最后产生各自的目标文件 //sln解决方案 //源代码被转换为可执行的机器指令(二进制指令) //每一个源文件()都会编译成俩个链接器 //连接器同时也会引入标准C型函数库中任何你人该程序 // //Linux下输入 gcc-e test.c(预编译/预处理) 文本操作 //预处理1#include头文件包含 预处理之后产生的结果都放在test.i中 //2.注释删除使用空格替换注释 //3.#define //经过这几步,test.c变成test.i //编译完成后,产生一个test.s的文件 编译完成之后就停下来,结果存在test.s // //汇编,把汇编代码转换成了2进制指令 文件变为text.o,汇编完成止呕就停下来,结果保存 //形成符号表add main//把程序里面的符号表 // //elf文件格式 //1合并段表 //add 0x100 没有ij之类的 //main 0x200 //2.符号表的合并和重定位 // //动态内存开辟是在堆空间上开辟 // //预处理详解 //预定义符号--文件已经定义好的符号 //-FILE- //进行编译的源文件 //__LINE__文件当前行号 //DATE 文件被编译日期 //__TIME__文件被编译时间 //_STDC 如果编译器遵循ANSIC,其值为1,否则未定义 // //#pragma pack(4) //#pragma //#if //#endif //#ifdef //#line

//宏的声明方式#define SQUARE(x) (x)(x) //宏的参数不是计算好替代进去,而是彻彻底底替换进去 #define SQUQRE(X) (X)(X)

#define CAT(X,Y)X##Y #define MAX(X,Y) ((X)>(Y)?(X):(Y))

struct S { char c1; int a; char c2; };

union Un { short s[7];//对齐数是2 int n;//对齐数是4 };

//void print(int a) //{ // printf("the value of a is %d\n", a); //} int main() {

//int a = 10;
//int b = 11;
//int max = MAX(a++, b++);
////int max = ((a++) > (b++) ? (a++) : (b++));//如果a++>b++,则a++是结果
//printf("%d\n", max);//12
//printf("%d\n", a);//11
//printf("%d\n", b);//13

//int a = 20;
//int b = 20;
//print(a);
//print(b);//函数做不到//把语句中的a换成b
//int Class84 = 2019;
//printf("%d\n", CAT(Class, 84));
//int ret = SQUQRE(5+1);
//printf("%d\n", ret);

//宏的优点:宏比函数在程序就规模和速度方面更胜一筹。
//	宏是类型无关的。
//	缺点:除非宏比较短,否则可能大幅度增加程序的长度
//	宏是没法调试的
//	宏由于类型无关,也就不够严谨
//	宏的参数可能出现类型,但是函数做不到
//	宏和函数都有副作用,但是函数不影响.
//把宏名全部大写,函数名不要全部大写

//命令行定义:可以放在编译的时候来调(某些需要经常变化的变量)

// int arr[10] = { 1,2,3,4,5,6,7,8,9,0 }; // int i = 0; // for (i = 0; i < 10; i++) // { // arr[i] = 0; //#ifdef DEBUG//如果之前没有定义过,那么里面的语句执行//预处理指令 // printf("%d ", arr[i]); //#endif // } // //#if 条件编译指令 //#endif //#if //#elif //#else //#endif

// 文件包含 // 本地文件包含用双引号来引用, // 查找策略:先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数 // 头文件一样在标准位置查找头文件。如果找不到就提示编译错误,linux环境的标准头文件路径: // <>也可以查找本地文件,但是效率较低 // 库文件包含用<> // // 如何避免头文件重复引入 //#ifndef TEST_H //#define TEST_H // //头文件的内容 //#endif //TEST_H // 或者 //#pragma once

//#define OFFSETOF(struct_name,member_name)(int)&(((struct_name*)0)->member_name)

//printf("%d\n", Offsetof(struct S, c1));
//printf("%d\n", Offsetof(struct S, a));
//printf("%d\n", Offsetof(struct S, c2));


//printf("%d\n", OFFSETOF(struct S, c1));//计算偏移量
//printf("%d\n", OFFSETOF(struct S, a));
//printf("%d\n", OFFSETOF(struct S, c2));

//unsigned char puc[4];
//struct tagPIM
//{
//	unsigned char ucPim1;
//	unsigned char ucData0 : 1;
//	unsigned char ucData1 : 2;
//	unsigned char ucData2 : 3;
//}*pstPimData;
//pstPimData = (struct tagPIM*)puc;
//memset(puc, 0, 4);
//pstPimData->ucPim1 = 2; //02四个bit合成一位
//pstPimData->ucData0 = 3;//29
//pstPimData->ucData1 = 4;//00
//pstPimData->ucData2 = 5;//00
//printf("%02x %02x %02x %02x\n", puc[0], puc[1], puc[2], puc[3]);
//printf("%d\n", sizeof(union Un));

union //联合体,总共两盒提大小是两个字节
{
	short k;//两个字节
	char i[2];//i数组是两个字节//这个应该叫柔性数组,不计入联合体大小
}*s, a;
s = &a;
s->i[0] = 0x39;
s->i[1] = 0x38;
printf("%x\n", a.k);//i和k占的是同一块空间,所以取i的时候,取的是k(栈区,先进后出,后进先出)
//小端储存(低位放在低地址,高位放在高地址,) 。打印显示低位在右端。

return 0;

}

举报

相关推荐

0 条评论