当前位置: 首页 > 编程笔记 >

C语言宏是简单的字符串替换

黄凌龙
2023-03-14
本文向大家介绍C语言宏是简单的字符串替换,包括了C语言宏是简单的字符串替换的使用技巧和注意事项,需要的朋友参考一下

示例

宏是简单的字符串替换。(严格来说,它们使用预处理令牌,而不是任意字符串。)

#include <stdio.h>

#define SQUARE(x) x*x

int main(void) {
    printf("%d\n", SQUARE(1+2));
    return 0;
}

您可能希望此代码可以打印9(3*3),但实际上5会被打印,因为宏将扩展为1+2*1+2。

您应该将参数和整个宏表达式括在括号中,以避免出现此问题。

#include <stdio.h>

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

int main(void) {
    printf("%d\n", SQUARE(1+2));
    return 0;
}

另一个问题是,不能保证对宏的参数进行一次评估。它们可能根本不会被评估,也可能会被评估多次。

#include <stdio.h>

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

int main(void) {
    int a = 0;
    printf("%d\n", MIN(a++, 10));
    printf("a = %d\n", a);
    return 0;
}

在此代码中,宏将扩展为((a++) <= (10) ? (a++) : (10))。由于a++(0)小于10,a++将被评估两次,这将使a和的返回值MIN与您预期的不同。

通过使用函数可以避免这种情况,但是请注意,类型将由函数定义固定,而宏对于类型可能(太)灵活。

#include <stdio.h>

int min(int x, int y) {
    return x <= y ? x : y;
}

int main(void) {
    int a = 0;
    printf("%d\n", min(a++, 10));
    printf("a = %d\n", a);
    return 0;
}

现在,双重评估的问题已解决,但是例如,此min函数无法处理double数据而不会被截断。

宏指令可以有两种类型:

#define OBJECT_LIKE_MACRO     followed by a "replacement list" of preprocessor tokens
#define FUNCTION_LIKE_MACRO(with, arguments) followed by a replacement list

区分这两种类型的宏的是标识符之后的字符#define:如果是lparen,则它是一个类似于函数的宏;否则,它是一个类似对象的宏。如果要编写类似函数的宏,则宏名称的末尾与之间不得有任何空格(。检查此内容以获取详细说明。

C99

在C99或更高版本中,您可以使用。static inline int min(int x, int y) { … }

C11

在C11中,您可以为编写“类型通用”表达式min。

#include <stdio.h>

#define min(x, y) _Generic((x), \
                        long double: min_ld, \
                        unsigned long long: min_ull, \
                        default: min_i \
                        )(x, y)

#define gen_min(suffix, type) \
    static inline type min_##suffix(type x, type y) { return (x < y) ? x : y; }

gen_min(ld, long double)
gen_min(ull, unsigned long long)
gen_min(i, int)

int main(void)
{
    unsigned long long ull1 = 50ULL;
    unsigned long long ull2 = 37ULL;
    printf("min(%llu, %llu) = %llu\n", ull1, ull2, min(ull1, ull2));
    long double ld1 = 3.141592653L;
    long double ld2 = 3.141592652L;
    printf("min(%.10Lf, %.10Lf) = %.10Lf\n", ld1, ld2, min(ld1, ld2));
    int i1 = 3141653;
    int i2 = 3141652;
    printf("min(%d, %d) = %d\n", i1, i2, min(i1, i2));
    return 0;
}

通用表达可以与多种类型的,例如被扩展double,float,long long,unsigned long,long,unsigned-和适当的gen_min宏调用写入。

 类似资料:
  • 大家好,我不需要答案,但我想知道并找出我做错了什么。作为一名初学者,我的学习任务非常“简单”。我需要创建一个字符串,在这个字符串中,我需要用其他单词替换一些单词,而不需要使用for循环:(我也想打印它,但我不知道该把Console.WriteLine放在哪里。谷歌搜索1小时不起作用,或者问了一个同事。 /*练习:与stringBuilder一起使用*猫变成小猫*狗变成小狗*老鼠变成小鼠*单词必须替

  • 在前面 C 语言的变量类型中介绍过 C 语言中的变量类型。不知道大家有没有注意到,在 C 语言中有字符类型的变量,但是没有其他编程语言中经常出现的字符串类型,在 JAVA 或者 C# 中用 string 这个关键字来声明其类型。但是在 C 语言中是没有这个变量类型的。 1. 字符串 在 C 语言中定义的字符串是一个由字符组成的数组,这个数组的最后一个元素是一个表示空的字符 。 字符串 abcde

  • 主要内容:字符串结束标志(划重点),字符串长度用来存放字符的数组称为 字符数组,例如: 字符数组实际上是一系列字符的集合,也就是 字符串(String)。在C语言中,没有专门的字符串变量,没有string类型,通常就用一个字符数组来存放一个字符串。 C语言规定,可以将字符串直接赋值给字符数组,例如: 数组第 0 个元素为 ,第 1 个元素为 ,第 2 个元素为 ,后面的元素以此类推。 为了方便,你也可以不指定数组长度,从而写作: 给字符数组赋

  • 本文向大家介绍Objective-C语言使用C字符串,包括了Objective-C语言使用C字符串的使用技巧和注意事项,需要的朋友参考一下 示例 转换NSString为const char使用-[NSString UTF8String]: -[NSString cStringUsingEncoding:]如果您的字符串使用非UTF-8编码,则也可以使用。 对于反向路径,请使用-[NSString

  • 在 C 语言中字符串的应用比较多,所以在这里我们实现一个函数,函数功能是将一串给定的字符串中的大写字符全部转换为小写字符。 1. 示例程序 在程序中,我们需要实现两个主要的功能,一个是将字符串中的每个字符都访问一次。另外一个就是将遍历过程中获取的大写字符转换为小写字符。 #include <stdio.h> #include <string.h> #include <ctype.h> int m

  • #define 叫做 宏定义命令,它也是C语言预处理命令的一种。所谓 宏定义,就是用一个标识符来表示一个字符串,如果在后面的代码中出现了该标识符,那么就全部替换成指定的字符串。 我们先通过一个例子来看一下 #define 的用法: 运行结果: 120 注意第 6 行代码 , 被 代替了。 就是宏定义, 为宏名, 是宏的内容(宏所表示的字符串)。在预处理阶段,对程序中所有出现的“宏名”,预处理器都会