c语言的宏定义_c语言变量类型有哪些

c语言的宏定义_c语言变量类型有哪些忘了啥时候记的笔记了@’TOC’宏定义宏定义是C提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、条件编译1.不带参数的宏定义:       宏定义又称为宏代换、宏替换,简称“宏”。格式:defi

大家好,欢迎来到IT知识分享网。

忘了啥时候记的笔记了
@

目录
    • 宏定义
      • 1.不带参数的宏定义:
      • 2.带参数的宏定义:
    • C语言宏定义技巧(常用宏定义)
      • 1,防止一个头文件被重复包含
  • define后面只要写个”文件名”保证其是一个独一无二的定义就可以了
      • 2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。
      • 3,得到指定地址上的一个字节或字
      • 4,求最大值和最小值
      • 5,得到一个变量的地址(word宽度)
      • 6,得到一个字的低位和高位字节
      • 7,将一个字母转换为大写
      • 8,返回数组元素的个数
      • 9,宏定义防止使用是错误

宏定义

宏定义是C提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、条件编译

1.不带参数的宏定义:

       宏定义又称为宏代换、宏替换,简称“宏”。 格式: #define 标识符 字符串 ,其中的标识符就是所谓的符号常量,也称为“宏名”。

       预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。 掌握”宏”概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。 即在对相关命令或语句的含义和功能作具体分析之前就要换:

       例: #define PI 3.1415926 ,把程序中出现的PI全部换成3.1415926

说明:
       (1)宏名一般用大写
       (2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义
       (3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
       (4)宏定义末尾不加分号;
       (5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。
       (6)可以用#undef命令终止宏定义的作用域
       (7)宏定义可以嵌套
       (8)字符串” “中永远不包含宏
       (9)宏定义不分配内存,变量定义分配内存。

2.带参数的宏定义:

       除了一般的字符串替换,还要做参数代换

       格式: #define 宏名(参数表) 字符串 例如:#define S(a,b) a * b ,area=S(3,2);第一步被换为area=a*b; ,第二步被换为area = 3 * 2;

类似于函数调用,有一个哑实结合的过程:
       (1)实参如果是表达式容易出问题 ,#define S ( r ) r * r ,area=S(a+b);第一步换为area=r * r;,第二步被换为area=a+b * a+b; 正确的宏定义是#define S ( r ) (( r ) * ( r ))
       (2)宏名和参数的括号间不能有空格
       (3)宏替换只作替换,不做计算,不做表达式求解
       (4)函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前进行,不分配内存
       (5)宏的哑实结合不存在类型,也没有类型转换。
       (6)函数只有一个返回值,利用宏则可以设法得到多个值
       (7)宏展开使源程序变长,函数调用不会
       (8)宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值)

       

C语言宏定义技巧(常用宏定义)

       写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性

1,防止一个头文件被重复包含

#ifndef TEST_H    // 1
#define TEST_H    // 2
//.......... // 一些声明语句
#endif               // 3

       以上代码:如果没有定义TEST_H变量,就继续往下执行,如果定义了,就直接endif,即不做任何操作。

       如果一个文件中包含了两个同样的头文件,那么第一次调用这个头文件的时候,没有定义TEST_H,经过1,到达2,定义TEST_H,进行代码段的执行,到3结束。但是当第二次调用头文件时,已经定义了TEST_H,所以就不会进行下面的代码声明了。这就是条件编译进行防止头文件包含的原理

define后面只要写个”文件名“保证其是一个独一无二的定义就可以了

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) ) ) 

        这东西我没咋用过。倒是当年写汇编的时候会直接对内存地址进行操作,c我没这么用过,主要是不知道确切地址,

4,求最大值和最小值

#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) ) 

#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) ) 

        三目运算符代替函数,算是常用的一个操作。

5,得到一个变量的地址(word宽度)

#define B_PTR( var ) ( (byte *) (void *) &(var) ) 

#define W_PTR( var ) ( (word *) (void *) &(var) ) 

6,得到一个字的低位和高位字节

#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255)) //得到低位

#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8)) //得到高位

7,将一个字母转换为大写

#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) ) 

        当时比较菜

8,返回数组元素的个数

#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )

        也是个常用的方法,大一的时候比较菜,投机取巧嘛

9,宏定义防止使用是错误

        用小括号包含。例如

#define ADD(a,b) (a+b) 

        可以看到上面的一些宏定义看上去有些是不必要的小括号,其实都是一次次试出来的,都是必要的

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/29771.html

(0)
上一篇 2023-10-08 17:00
下一篇 2023-10-13 10:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信