C语言中的符号常量 (#define语句)

5
在阅读完 K&R 的《C 程序设计语言》之后,我遇到了 #define 符号常量。我决定定义...
#define INTEGER_EXAMPLE 2
#define CHAR_EXAMPLE 2

所以我的问题是,C语言如何知道我定义的是int类型还是char类型?


只是提供信息,你只能接受一个答案,只点击一个正确的...哈哈 - Grijesh Chauhan
7个回答

10

#define -d的名称没有类型。它们只是定义文本替换。

编译器看到的是预处理形式。如果使用GCC,请尝试gcc -C -E somesource.c并查看(预处理后)的输出。

在20世纪80年代,预处理器是一个独立的程序。

阅读有关cpp预处理器以及预处理器C预处理器维基页面的内容。

您甚至可以定义不明确的名称,例如

#define BAD @*?$ some crap $?

而且更可怕的是,您甚至可以定义语法不完整的内容,例如

#define BADTASTE 2 +

并且后来的代码是 BADTASTE 3

实际上,在定义宏时需要使用括号。如果你有以下代码:

#define BADPROD(x,y) x*y

那么 BADPROD(2+3,4+5) 展开为 2+3*4+5,编译器会将其理解为 2+(3*4)+5;你真正想要的是:

#define BETTERPROD(x,y) ((x)*(y))

所以BETTERPROD(2+3,4+5)被展开为((2+3)*(4+5))

避免宏参数中的副作用,例如BETTERPROD(j++,j--)

通常要谨慎使用宏,并使其保持简单。


3
关于这些定义,它们没有类型,扩展的宏也没有。处理 #define 的预处理器只是在源代码中替换文本。
当你在某处使用这些定义时,例如:
int i = INTEGER_EXAMPLE;

这将会扩展为

int i = 2;

这里将字面量2(在这个上下文中是一个int类型)赋值给一个int变量。

你也可以这样做:

char c = INTEGER_EXAMPLE;

在这里,字面值2是一个int类型,并被分配给char类型。尽管2在char类型的限制范围内,但一切都很顺利。

你甚至可以这样做:

int INTEGER_EXAMPLE = 2;

这将扩展为:
int 2 = 2;

这不是有效的C语言代码。


3

#define STRING VALUE

这只是预处理器的指令,它会将STRING替换为VALUE。之后编译器将接管并检查类型。


2

并不是这样的,这是预处理器的作用。常量的类型取决于其使用的上下文。例如:

#define INT_EXAMPLE 257

char foo = INT_EXAMPLE;

尝试在char上下文中分配257,这应该会生成警告,除非您的计算机上的char具有超过8位。


2

#定义仅是值的文字替换。您可能想使用它来简化代码或提高代码可读性。

static const

由于其范围和类型安全性。请尝试以下方法:

#define main no_main

int main()  // gets replaced as no_main by preprocessor
{
    return 0;
}

应该会出现链接错误。或者你可以尝试通过这种方式愚弄你的老师。

#define I_Have_No_Main_Function main //--> Put this in header file 1.h

#include"1.h"

int I_Have_No_Main_Function()
{
    return 0;
}

1
它并不会影响。在编译器开始工作之前,#define语句已被处理。基本上预处理器会搜索你所写的内容并进行替换,例如,所有INTEGER_EXAMPLE的实例都将被替换为字符串2。
根据使用位置,编译器决定那个2的类型。
int x = INTEGER_EXAMPLE; // 2 is an integer
char y = INTEGER_EXAMPLE; // 2 is a char

1

预处理程序无法知道宏定义的类型。预处理程序将仅使用“2”替换所有出现的“CHAR_EXAMPLE”。我会使用强制转换:

#define CHAR_EXAMPLE ((char)2)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接