成长之路---C语言笔记(宏定义)

简介: 成长之路---C语言笔记(宏定义)

预处理


预处理是指程序在编译之前所进行的处理。预处理命令最大的特征是以“#”开头,如#include、#define等。在C语言中的预处理主要包括三方面的内容:宏定义、文件包含以及条件编译。合理地使用预处理命令,有利于程序的阅读、调试和不同平台间的移植。


宏定义


宏,就是将一组命令组合在一起,作为一个独立的命令完成一系列任务。在C语言的源程序中允许用一个标识符来表示一个字符串,此时该标识符被称为宏名,而该字符串被称为宏体。包含宏定义的程序在编译预处理的时候,预处理程字将会对程序中所有出现宏名的地方都用宏体去代替,该过程被称为宏替换。

在C语言中,宏分为带参数和不带参数两种。


不带参数的宏定义


//#define 宏名 字符串//不带参数的宏定义
#define Max 100


其作用为用宏名Max去代替字符串100,当编写源代码时所有需要使用100的地方都可以用Max来代替,当我们对源程序编译时,先由源程序进行宏替换,即用100来置换使用宏名Max后再进行编译。

常见问题:


#define<stdio.h>
#define Max  100+y
int main()
{
int s,y;
scanf("%d",&y);
s=Max*2;
printf("%d",s);
}


*这里我们容易简单的认为替换后的Max为(100+y)2,事实上并非如此,宏定义是简单的替换真实情况应该wei(100+y2),为了预防这种误解,在我们编写程序的时候可以加上括号(100+y),我们还应注意 *

1. 宏替换只是一种简单的替换,在任何时候它都是用字符串来取代宏名,所以任何错误都是编译是被发现的,在预处理时不作任何检查。

2. 宏定义并不是语句,所有不需要在其后面加上分号,加分号不会报错,但在一些情况下也会造成不必要的错误。

3. 诺在程序之前需要解除某个宏定义的作用域,则需要所有(#undef)


#define Max 100
...
int main()
{
}
#undef Max
...
void fi()
{
...
}


其作用在于,Max宏只在main()函数中有效,而对于f1函数无效。

4. 诺在程序中用引号将宏名括起来则预处理程序不对其进行宏替换。如:


#define Max 100
int main()
{
printf("Max");
}


5. 宏定义允许嵌套使用,如后一个宏去使用前一个宏的定义。


#define Max 100
#define Math Max*2


带参数的宏定义


在C语言中,宏定义还可以带参数,在宏定义中使用的参数称为形式参数,而在宏替换后所用的参数称为实际参数,这与函教定义和调用过程中是一致的。


#define 宏名(形式参数表) 字符串
//在调用时
宏名(实际参数表)如
#define Max(x) 100*x*y
k=Max(10);
//在宏调用编译后,其就会变为k=100*10*10;


同样带参数的宏我们也需要注意以下问题:


1. 宏名和参数表之间不能有空格,否则会将宏名后面的字符串替换。

2. 与无参数的宏定义一样,带参数的宏更需要注意括号的使用。因为对于带参数的宏来说,其参数可以是表达式,在某些时候如果不使用括号的话会产生意想不到的后果。


#include<stdio.h>
#define Math() y*y
int main()
{
    int a,b;
    a=3;
    b=Math(a+1);
}


在该程序中我们不难看出,宏替换后b=Math()变为了b=a+1a+1,显然我们每天达到预期的结果诺我们在进行宏定义时加上括号,就可以有效的避免这种情况。

3. 注意带参数的宏与函数的区别,有时两者得到得结果一致,但有时两者又有很大区别*


#include<stdio.h>
#define Math(y) ((y)*(y))
int Math2(int c)
{
return ((y)*(y))
}
int main()
{
int a,b;
a=3;
b=Math(a++);
//b=Math(a++)
}


上面是使用宏定义和函数进行编写的例子,从形式上来看, 两者都差不多。但是对于前者来说,由于是宏定义,因此在预编译的时候发生了宏替换,即语句“b=Math(a++);"变为“b=((a++)(a++));";由于具有++操作,当执行首面的a++操作后,a实际上变为4,因此该语句实际上是进行了b=34操作。对于后者来道由于使用的是函数,只是在传参时将a+传入, 因此结果是b=33.由此可见,宏定和函数虽然在形式上相似,但其本质是不同的。*


每日一题


对正整数1234567890987654321123456789,计算其各位数字之和,⽤汉语拼⾳顺序输出和的

每⼀位数字(输出⽤逗号分隔)

输出:yi san wu

最后的话 :如果大家觉得这篇文章对你们有帮助的话希望你们能够点点关注,你们的关注是我继续写下去的动力,谢谢大家。


答案及解析


思路:1. 由n的值已经超过long long类型的范围可知只能用字符数组储存

使用字符数组储存数字也能更好地分割每一位数

2. 遍历字符数组将每个字符转换为数字进行累加

3. 由于每个数字的拼音刚好对应该数字的数组下标,故可以直接设置一个二维字符数组存储

4. 将累加值的每一位数字逆序输出即可


#include<stdio.h>
int main(void){
int i,n=0,m,wxx3[101];
char wxx[10][5]=
{"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
char wxx2[101]="1234567890987654321123456789";
//wxx2[i]-'0'即可将字符转换为数字
for(i=0,m=0;wxx2[i]!='\0';i++)
m+=wxx2[i]-'0';
//循环获取累加值的每一位数字
//因为每次获取的是右边的数字需要逆序输出
//故先使用数组保存起来
while(m){
wxx3[n++]=m%10;
m/=10;
}
//将数组存储的累加值各位数逆序输出对应的字符串
for(i=n-1;i>=0;i--)
printf("%s%c",wxx[wxx3[i]],i!=0?' ':'\n');
return 0;
}
目录
相关文章
|
6月前
|
存储 人工智能 算法
【C语言】自学终极笔记
【C语言】自学终极笔记
108 0
|
6月前
|
C语言
C语言使用宏定义实现等级调试输出PRINT_LEVEL
C语言使用宏定义实现等级调试输出PRINT_LEVEL
126 0
|
3月前
|
测试技术 C语言 C++
【C语言刷题训练——6】鹏哥C语言刷题训练营笔记,含代码讲解改进
【C语言刷题训练——6】鹏哥C语言刷题训练营笔记,含代码讲解改进
|
3月前
|
存储 C语言
【C语言】鹏哥C语言刷题训练营——第5节内容笔记(含代码全面分析和改进,讲解)
【C语言】鹏哥C语言刷题训练营——第5节内容笔记(含代码全面分析和改进,讲解)
|
6月前
|
编译器 C语言
C语言宏定义(#define定义常量​、#define定义宏​、 带有副作用的宏参数、 宏替换的规则、 宏函数的对比)
C语言宏定义(#define定义常量​、#define定义宏​、 带有副作用的宏参数、 宏替换的规则、 宏函数的对比)
|
5月前
|
程序员 C语言
C语言中的宏定义:从常量到高级技巧
C语言中的宏定义:从常量到高级技巧
280 1
|
5月前
|
C语言
|
5月前
|
C语言
|
6月前
|
C语言
C语言(指针详解)重点笔记:指针易错点,都是精华
C语言(指针详解)重点笔记:指针易错点,都是精华
76 0
|
6月前
|
编译器 C语言
【C语言】什么是宏定义?(#define详解)
【C语言】什么是宏定义?(#define详解)
111 0