大一C语言学习之:一篇水文,宏的使用

1.引言

         不久前在学习有关于#define预处理指令,宏定义的使用,发现了一些平时不注意或是平时想不通的细节。下面就来说下我的体会吧。

2.编译相关实现

         关于宏常量,一开始学习C的语言的人应该都有一定的了解,它的作用就是简单的代码替换。在编译器执行编译前会先执行以下几个操作:

  1. 若是设置了ANSI C的编译器,会将一部分的扩展字符替换(想了解的可以自行查找有关三字符序列和双字符的资料)
  2. 替换所有注释为空格
  3. 替换宏常量为其代替值

所以运用宏可以实现一些比较方便的功能,对于一些不需要长期修改的数据,或是简单的函数功能可以使用#define预处理的指令。

3.简单的#define预处理指令

a.没有参数的宏

         此类的宏定义,主要用于文本替换或是数据替换,在C中此类的宏最为常见,也最为常用。在ACM、蓝桥杯、CCSP等算法竞赛中,经常会把数组的最大下标通过宏定义的方法给出,以方便调试

如下的代码实例:

#include <stdio.h>
#define LEN 500
#define WORDS "I like C"

int main(void)
{
	char str1[LEN] = WORDS;

	puts(str1);
	return 0;
}

         这段示例定义了字符数组str1,并把字符串WORDS赋值给这个数组,这是C中数组和常量配合使用的最常见例子。

b.带参数的宏

         你可以定义具有形式参数(简称“形参”)的宏。当预处理器展开这类宏时,它先使用调用宏时指定的实际参数(简称“实参”)取代替换文本中对应的形参。带有形参的宏通常也称为类函数宏(function-like macro)。以下是带参数宏的基本定义方法:

#define 宏名称( [形参列表] ) 替换文本
#define 宏名称( [形参列表 ,] ... ) 替换文本

         另外,stdio.h中,编译器常常使用宏函数来定义getchar()和putchar(),目的是使用预处理指令,提供编译和运算的速度。如下两个函数在头文件(stdio.h)中的定义:

#define getchar() getc(stdin)
#define putchar(x) putc(x, stdout)

         这里需要注意的是,在定义一个宏时,必须确保宏名称与左括号之间没有空白符。如果在名称后面有任何空白,那么命令就会把宏作为没有参数的宏,且从左括号开始采用替换文本。如下代码片段(有缺陷)

#include <stdio.h>
#define SQUARE(x) x*x
#define PR(x) printf("The result is %d.\n", x)

int main(void)
{
	int x;
	
	x = SQUARE(5);
	PR(x);		//输出:The result is 25.
	x = SQUARE(5 + 3);
	PR(x);		//输出:The result is 23.
	
	return 0;
}

         从上诉代码的运行结果来看,函数SQUARE(x)的作用是求x2,但如果按照函数的思想,第二个运算应该求8*8的结果,而宏函数却输出了23。其原因在于宏这是简单的进行了文本的替换,没有实际的过程和返回值,如上的代码展开为:x = 5 + 3 * 5 + 3;所有按照乘法和加发的优先级来计算,此时x=5+15+3=23。
         因此上实例的宏定义可以改成:

#define SQUARE(x) ((x)*(x))

         这样展开就变成了x=((5+3)*(5+3));可以成功的计算出所需要的结果。

4.C语言函数库内置的宏

         在C语言的很多头文件中,都含有丰富的宏定义,使用这些宏可以大大的简化程序,加快速度。我整理了一些常用的头文件中的部分宏定义,希望和我一样的小白同学可以多了解下~

  1. stdio.h
#define EOF     (-1)		//这个宏听说在处理文件的时候很常用的哦~我们可以试着使用下
#define getchar() getc(stdin)
#define putchar(x) putc(x, stdout)
  1. math.h
    这个头文件大多是关于数学的函数,宏常量这些,有些挺好用的,基本都是干货。(PS:可能很多想我这样的大一同学,并不知道这个库中关于PI,LN这些的宏定义,那我就来普及下~~)
#define M_E        2.71828182845904523536		//指数e
#define M_LOG2E    1.44269504088896340736		//log2E
#define M_LOG10E   0.434294481903251827651		//log10E
#define M_LN2      0.693147180559945309417		//ln2
#define M_LN10     2.30258509299404568402		//ln10
#define M_PI       3.14159265358979323846		//PI
#define M_PI_2     1.57079632679489661923		//PI/2
#define M_PI_4     0.785398163397448309616		//4/PI
#define M_1_PI     0.318309886183790671538		//2/PI
#define M_SQRT2    1.41421356237309504880		//根号2
  1. limtis.h
    这个头文件中多是有关各种类型的大最小值,在一些不确定的极值题中可以使用这些宏方便快捷。
//由于说明中官方文档中已有了注释,那我就不重复劳动添加注释啦
#define SHRT_MIN    (-32768)        /* minimum (signed) short value */
#define SHRT_MAX      32767         /* maximum (signed) short value */
#define USHRT_MAX     0xffff        /* maximum unsigned short value */
#define INT_MIN     (-2147483647 - 1) /* minimum (signed) int value */
#define INT_MAX       2147483647    /* maximum (signed) int value */
#define UINT_MAX      0xffffffff    /* maximum unsigned int value */
#define LONG_MIN    (-2147483647L - 1) /* minimum (signed) long value */
#define LONG_MAX      2147483647L   /* maximum (signed) long value */
#define ULONG_MAX     0xffffffffUL  /* maximum unsigned long value */
#define LLONG_MAX     9223372036854775807i64       /* maximum signed long long int value */
#define LLONG_MIN   (-9223372036854775807i64 - 1)  /* minimum signed long long int value */
#define ULLONG_MAX    0xffffffffffffffffui64       /* maximum unsigned long long int value */

#define _I8_MIN     (-127i8 - 1)    /* minimum signed 8 bit value */
#define _I8_MAX       127i8         /* maximum signed 8 bit value */
#define _UI8_MAX      0xffui8       /* maximum unsigned 8 bit value */

#define _I16_MIN    (-32767i16 - 1) /* minimum signed 16 bit value */
#define _I16_MAX      32767i16      /* maximum signed 16 bit value */
#define _UI16_MAX     0xffffui16    /* maximum unsigned 16 bit value */

#define _I32_MIN    (-2147483647i32 - 1) /* minimum signed 32 bit value */
#define _I32_MAX      2147483647i32 /* maximum signed 32 bit value */
#define _UI32_MAX     0xffffffffui32 /* maximum unsigned 32 bit value */

/* minimum signed 64 bit value */
#define _I64_MIN    (-9223372036854775807i64 - 1)
/* maximum signed 64 bit value */
#define _I64_MAX      9223372036854775807i64
/* maximum unsigned 64 bit value */
#define _UI64_MAX     0xffffffffffffffffui64

总结谢语

         这是我大学第一次总结前面所学知识写的博客,里面包括了我自己认为需注意的点和一些宏的总览。若是在语句等方面有不足的请多多谅解,也恳请大家在评论中留言、讨论,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值