玉树商城网站建设,wordpress网址域名,企业网站 asp源码,wordpress配置页面预定义符号 c语言中设置一些预定的符号#xff0c;我们可以直接使用 //列#xff1a;
__FILE__ //进⾏编译的源⽂件
__LINE__ //⽂件当前的⾏号
__DATE__ //⽂件被编译的⽇期
__TIME__ //⽂件被编译的时间
__STDC__ //如果编译器遵循ANSI C#xff0c;其值为1#xff0c;否…
预定义符号 c语言中设置一些预定的符号我们可以直接使用 //列
__FILE__ //进⾏编译的源⽂件
__LINE__ //⽂件当前的⾏号
__DATE__ //⽂件被编译的⽇期
__TIME__ //⽂件被编译的时间
__STDC__ //如果编译器遵循ANSI C其值为1否则未定义 / 续行符号
int main()
{printf(file %s\nline %d\ndate %s\ntime %s\n, \__FILE__, __LINE__, \__DATE__, __TIME__);return 0;
}
#define 用法 //定义常量
#define max 100
int main()
{printf(%d\n, max);return 0;
} //给关键字创建一个别的名称
#define i int
i main()
{i a 10;printf(%d\n, a);return 0;
}
我们平时使用代码时结尾都是以;那么#define后面需不需要加上呢
#define min 1;
#define max 1
int main()
{printf(%d\n, min); //errprintf(%d\n, max);return 0;
}答案是不能因为在预处理阶段编译器会删除所有的#define并且替换定义的变量 拿上面的代码举例 下面是预处理替换后的代码
int main()
{printf(%d\n, 1;);printf(%d\n, 1);return 0;
}
#define 定义宏 - 可以传入参数 //比如
#define add(x) x * x
int main()
{printf(%d\n, add(2 1));return 0;
}
这段代码会输出多少有木有小伙伴算的是9毕竟3*3是9那么这样就错了 下面我们一起来看看
首先我们前面了解到#define的内容会直接被替换 替换后
int main()
{printf(%d\n, 2 1 * 2 1);return 0;
}
// 根据优先级 21*21 5
// 这种直接的替换往往也会带来一些小麻烦要想解决也很容易只要勤加就行了#define add(x) (x)*(x)
int main()
{printf(%d\n, add(2 1));return 0;
}
#endif//这样就不用担心优先级带来的麻烦了//这样就真的改好了吗我们来看下面一段代码
#define add(x) (x)(x)
int main()
{printf(%d\n, 10 * add(5)); //我们想要的结果是100return 0;
}// 输出的确实55这还是犯了与上面同样的问题我们的加少了
// 最好的方案是在外面一层也加上#define add(x) ((x)(x))
int main()
{printf(%d\n, 10 * add(5));return 0;
} 带有副作用的宏参数 举例
#define MAX(a, b) ((a) (b) ? (a) : (b))
int main()
{int a 3;int b 10;int z MAX(a, b);printf(%d\n %d\n %d\n, a, b, z);return 0;
}//由上面的函数我们来进行替换
int main()
{int a 3;int b 10;int z ((a) (b) ? (a) : (b));// 先执行(a)(b) - a4, b11;// 因为ab, 所以执行表达式2(b) - a4,z11,b12printf(%d\n%d\n%d\n, a, z, b);return 0;
}//这就是宏参数的副作用如果换成函数又如何呢
int fution(int a, int b)
{return a b ? a : b;
}int main()
{int a 3;int b 10;int z fution(a, b);printf(%d\n%d\n%d\n, a, z, b);return 0;
}//我们可以看见z的结果是10而ab的结果分别加了1函数在传参后函数中a与b不再改变。
宏替换的规则
1.在调⽤宏时⾸先对参数进⾏检查看看是否包含任何由#define定义的符号。如果是它们⾸先被替换。2. 替换⽂本随后被插⼊到程序中原来⽂本的位置。对于宏参数名被他们的值所替换。3. 最后再次对结果⽂件进⾏扫描看看它是否包含任何由#define定义的符号。如果是就重复上述处理过程。
注意
1. 宏参数和#define定义中可以出现其他#define定义的符号。但是对于宏不能出现递归。2. 当预处理器搜索#define定义的符号的时候字符串常量的内容并不被搜索。 宏函数的对比
// 宏函数常常应用于比较简单的运算// 如比较大小// 宏写#define MAX(a, b) ((a)(b)?(a):(b))
int main()
{printf(%d\n, MAX(2, 3));return 0;
}// 函数写int MAX(int a, int b)
{return a b ? a : b;
}
int main()
{printf(%d\n, MAX(2, 3));return 0;
}
为什么使用宏来运算而不使用函数 1. 相比较函数的调用直接替换的计算工作时间更快 2. 宏与类型无关你可以比较任意类型然而函数却需要更改返回类型
宏函数的劣势 1.使用宏的时候就相当于插入一段定义的代码如果宏过长会导致代码太多不好观察 2.宏无法调试 3.宏可能会带来优先级的问题与类型也无关不够严谨 #和## #运算符 //#运算符
// #运算符所执行的操作可以将宏中的一个参数转换为字符串字面量//如我们有一个变量 int a 20;
//我们想要使用宏然后打印出 the num of a is 20.#define PRINT(n) printf(the num of #n is %d,n);
int main()
{int a 20;PRINT(a);return 0;
}当我们按照下⾯的⽅式调⽤的时候
PRINT(a);//当我们把a替换到宏的体内时就出现了#a⽽#a就是转换为a这时⼀个字符串
代码就会被预处理为
printf(the num of a is %d,a); ##运算符
#define FUNTION_MAX(type) \
type type##_max(type a, tpye b)\
{ \return (a b ? a : b); \
}// 这样使用后我们可以传入不同类型的参数了 命名约定 我们一般宏的使用命名时都全部大写对于函数的应用却不全部大写
#undef
这条命令可以移除一个宏定义
#define MAX 100
int main()
{printf(%d\n, MAX);
#undef MAXprintf(%d\n, MAX); //errreturn 0;
}
条件编译 有时我们需要用一段代码但用后后面可能还要使用我们希望保留并且设定一个开关这就是条件编译
#define __DEBUG__
int main()
{int i 0;int arr[10] { 0 };for (i 0; i 10; i){arr[i] i 1;
#ifdef __DEBUG__printf(%d , arr[i]);
#endif}return 0;
}
// 这样之后我们只有在前面定义 __DEBUG__ 我们才可以使用中间的代码