1 防止一个头文件重复定义
格式如下
#ifndef COMDEF_H
#define COMDEF_H
//头文件内容
#endif
这个在很多的头文件的开头都有看到,就是弄不明白,什么叫重复定义???试个程序看看
• 例题 1 test1.c
#include <stdio.h>
int main(int argc,char *argv[])
{
printf("lsdkfla\n");
}
• 例题 2 test2.c
#include <stdio.h>
#include <stdio.h>
int main(int argc,char *argv[])
{
printf("lsdkfla\n");
}
现用动态文件的方法编辑
gcc test1.c -Wall
编译结构,没有错误,肯定的。。。。
gcc test2.c -Wall
哦,也没有错误???那这个有什么用呢!!!
不理解,是不是能在 test2.c 编译的结构中 a.out 中会有两个标准库 stdio.h 的库连接呢,我编译静态。 编译成静态文件:
gcc -Wall -static test1.c -o test1
编译结果,没有错误!
gcc -Wall -static test2.c -o test2
编译结构,也没有错误啊!!!!
那用 ls -l 查看文件大小,哦,一样大。。。
那个功能是什么作用呢,想了好久。。。
突然想起来自己写一个头文件看看
• 例题 3 test.h main.c
/test.h/
#include <stdio.h>
int test(int a)
{
printf("test ...\n");
}
/main.c/
#include "test.h"
int main(int argc, char *argv[])
{
test(4);
}
编译方法:
gcc -Wall main.c
编译结果,没有错误。。。。 继续试验。。。。。
• 例题 4 test.h main.c
/test.h/
#include <stdio.h>
int test(int a)
{
printf("test ...\n");
}
/main.c/
#include "test.h"
#include "test.h"
int main(int argc,char *argv[])
{
test(4);
}
编译结果: 终于出错了啊!!!!呵呵!!!
test.h:3: 错误: ‘test’ 重定义
test.h:3: 错误: ‘test’ 的上一个定义在此
终于弄明白了。。。。。那么我加上宏定义看看!!!!
例题 5 test.h main.c
/test.h/
#ifndef _TEST_H
#define _TEST_H
#include <stdio.h>
int test(int a)
{
printf("test ...\n");
}
#endif /结束_TEST_H/
/main.c/
#include "test.h"
#include "test.h"
int main(int argc,char *argv[])
{
test(4);
}
编译方法:
gcc -Wall main.c
编译结果: 程序正常完成编译,没有出错信息。。。。
2 防止由于各种平台和编译器的不同,而产生的类型字节数
typedef unsigned char boolean; /* Boolean value type. */
typedef unsigned long int uint32; /* Unsigned 32 bit value */
typedef unsigned short uint16; /* Unsigned 16 bit value */
typedef unsigned char uint8; /* Unsigned 8 bit value */
typedef signed long int int32; /* Signed 32 bit value */
typedef signed short int16; /* Signed 16 bit value */
typedef signed char int8; /* Signed 8 bit value */
3 得到指定地址上的一个字节或字
取得指定地址的一个字
*#define MEM_B(x) (*((byte )(x)))
取得指定地址的一个字
*#define MEM_W(x) (*((word )(x)))
例题 1 test.c
#include <stdio.h>
#define MEM_B(x) (*((byte *)(x)))
int main(int argc,char *argv[])
{
char a='c';
printf("&a==%c \n",MEM_B(&a));
}
编译方法:
gcc -Wall test.c
执行结果:
&a==c
4 求最大值和最小值
定义方法:
#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )
例题:test.c
#include <stdio.h>
#define MAX(x,y) (((x)>(y))?(x):(y))
int main(int argc,char *argv[])
{
printf("max==%d \n",MAX(4,5));
}
编译方式:
#gcc -Wall test.c
执行结果:
#max==5
5 得到一个 field 在结构体(struct)中的偏移量
定义方法:
#define FPOS( type, field ) ( (dword) &((( type *) )0)-> field )
这个是最郁闷的一个,终于搞定了!!!!郁闷的 typedef 和运算规则 例题 test.c
#include <stdio.h>
typedef unsigned long dword;
#define FPOS( type,field) (dword)&(((type *)0)->field)
typedef struct test
{
int a;
int b;
char c ;
}d;
int main(int argc,char *argv[])
{
printf("offset==%d \n",FPOS(d,b));
}
编译方法:
gcc -Wall test.c
执行结果
offset==0x4
“&”的运算级别小于“->”运算级别
特别推荐 C 语言运算符表
6 得到一个结构体中 field 所占用的字节数
定义方法:
#define FSIZ(type,field) sizeof(((type *) 0)->field )
例题: test.c
#include <stdio.h>
#define FSIZ(type,field) sizeof(((type *) 0)->field)
struct test
{
int a;
int b;
char c;
};
int main(int argc,char *argv[])
{
printf("sizeof==%d \n",FSIZ(struct test,b);
}
编译方法:
gcc -Wall test.c
执行结果
sizeof=4
7 按照 LSB 格式把两个字节转化为一个 Word
提示: LSB 和 MSB 的定义
• LSB(Least Significant Bit)是**“意义最小的字位”**。
• MSB(Most Significant Bit)是**“意义最大的字位”**
定义格式
#define FLIPW(ray) ((((word)(ray)[0])* 256)+(ray)[1])
例题 test.c
#include <stdio.h>
typedef unsigned short word;
#define
FLIPW(ray) ((((word)(ray)[0])* 256)+(ray)[1])
int main(int argc,char *argv[])
{
char test[2]={0x06,0x07};
printf("LSB==%d \n",FLIPW(test));
}
这个数是 6*256+5=1541 突然见有了个想法,可以不可以变成大字节的顺序,看一下。。。
例题:test.c
#include <stdio.h>
typedef unsigned short word;
#define
FLIPW(ray) ((((word)(ray)[1])* 256)+(ray)[2])
int main(int argc,char *argv[])
{
char test[2]={0x06,0x07};
printf("LSB==%d \n",FLIPW(test));
}
编译方法:
gcc -Wall test.c
执行结构
1286
这个数是 5*256+6=1286