宏定义不是C语句,不必在行未加分号;
define命令出现在程序中函数的外面,宏名的有限范围为定义命令之后到本源文件结束。
可以用#undef命令终止宏定义的作用域。
对程序中用双撇号括起来的字符串内的字符,不进行置换。
宏定义与定义变量不同,只作字符替换,不分配空间;
带参数的宏定义(不只是进行简单的字符串替换,还要进行参数替换)
带参数的宏定义与函数时不同的,主要有以下几点:
函数调用时,先求出实参表达式的值,然后带入形参。而宏只是进行简单的字符替换。
函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏展开则是编译前进行的,在展开时不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。
对函数中的实参和形参都要定义类型,二者要求一致。而宏不存在类型问题,宏名无类型。宏定义时,字符串可以是任何类型的数据。
调用函数只可得到一个返回值,而用宏定义可以设法得到几个结果。
使用宏次数多时,宏展开后源程序变长,而函数调用不会。
宏替换不占运行时间,只占编译时间。而函数调用则占运行时间(分配内存,保留现场,返回值)
文件包含
所谓“文件包含”处理就是指一个源文件可以将另一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中。(#include…)
头文件除了可以包含函数原型和宏定义外,也可以包括结构体类型定义和全局变量定义等。
条件编译
程序中的某一部分需要满足一定条件时才进行编译,也就是对这一部分内容指定编译的条件,这就是条件编译。
条件编译有以下几种形式:
#ifdef 标识符
程序段1
#else
程序段2
#endif
#if 表达式
程序段1
#else
程序段2
#endif
//条件编译
#include<stdio.h>
#define LETTER 1
void main()
{
char str[20]="C Language",c;
int i=0;
while((c=str[i]!='/0'))
{
i++;
#if LETTER
if(c>='a'&&c<='z')
c=c-32;
#else
if(c>='A'&&c<='Z')
c=c+32;
#endif
printf("%c",c);
}
printf("/n");
}
if、#ifdef、#if defined之间的区别
if的使用说明
if的后面接的是表达式
#if (MAX==10)||(MAX==20)
code...
#endif
它的作用是:如果(MAX==10)||(MAX==20)成立,那么编译器就会把其中的#if 与 #endif之间的代码编译进去(注意:是编译进去,不是执行!!)
if defined的使用
#if后面接的是一个宏。
#if defined (x)
...code...
#endif
这个#if defined它不管里面的“x”的逻辑是“真”还是“假”它只管这个程序的前面的宏定义里面有没有定义“x”这个宏,如果定义了x这个宏,那么,编译器会编译中间的…code…否则不直接忽视中间的…code…代码。
另外 #if defined(x)也可以取反,也就用?#if !defined(x)
ifdef的使用
#ifdef的使用和#if defined()的用法一致
#ifndef又和#if !defined()的用法一致。
最后强调两点:
第一:这几个宏定义只是决定代码块是否被编译!
第二:别忘了#endif
用typedef命名已有类型
?陷阱一:
记住,typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如:
先定义:
typedef char* PSTR;
然后:
int mystrcmp(const PSTR, const PSTR);
const PSTR实际上相当于const char吗?不是的,它实际上相当于char const。
原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const。
简单来说,记住当const和typedef一起出现时,typedef不会是简单的字符串替换就行。
陷阱二:
typedef在语法上是一个存储类的关键字(如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性,如:
typedef static int INT2; //不可行
编译将失败,会提示“指定了一个以上的存储类”。
1、typedef的用法
在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:
typedef??? int?????? INT;
typedef??? int?????? ARRAY[10];
typedef?? (int*)?? pINT;
typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。
2、#define的用法
(#define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它的实例像:)
#define?? INT???????????? int
#define?? TRUE???????? 1
## 学习分享
在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了
很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘
如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。
**2021最新上万页的大厂面试真题**
![](https://s2.51cto.com/images/20210827/1630060469731160.jpg)
**七大模块学习资料:如NDK模块开发、Android框架体系架构...**
![](https://s2.51cto.com/images/20210827/1630060470268688.jpg)
只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。
> 这份体系学习笔记,适应人群:
> **第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。
> **第二,**开发几年,不知道如何进阶更进一步,比较迷茫。
> **第三**,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!
> 由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。**如有需要获取完整的资料文档的朋友[点击我的腾讯文档免费获取](https://gitee.com/vip204888/android-p7)。**
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/115138.html