简体   繁体   English

定义常量的数据类型是什么?

[英]What is the datatype of a defined constant?

I was trying this code. 我正在尝试这段代码。

#include <stdio.h>
#include <stdlib.h>
#define LOWER 0
#define UPPER 300

int main()
{
    printf("%d %f",LOWER,UPPER);
    return 0;
}

I read some of the answers and it says that defined constants don't have a type and are not allocated any memory. 我读了一些答案,它说定义的常量没有类型,也没有分配任何内存。 Then why is it giving errors if i specify different type specifiers in printf()? 那么,如果我在printf()中指定不同的类型说明符,为什么会出错呢?

In this case, the type is the type of the literal constants. 在这种情况下,类型是文字常量的类型。 Both 0 and 300 are integer constants that fit in an int , so their type is int . 0300都是适合int整数常量,因此它们的类型是int

In your example, both are pushed into the variadic parameter list of printf as int values. 在您的示例中,两者都作为int值被推入printf的可变参数列表中。 This can cause problems with the format flags in the format string of printf() do not match the underlying type. 这可能会导致printf()格式字符串中的格式标记与底层类型不匹配。 Refer to this post for reasons why undefined behavior can ensue. 请参阅此文章 ,了解可能导致未定义行为的原因。

As hideous as it seems, one way to know you can get what you're looking for in this printf is to do this: 看起来很可怕,知道你可以在这个printf找到你想要的东西的一种方法就是这样做:

#include <stdio.h>
#include <stdlib.h>
#define LOWER 0
#define UPPER 300

int main()
{
    printf("%d %f", (int)LOWER, (float)UPPER);
    return 0;
}

In both cases, these are preprocessor macros that are substituted before compilation. 在这两种情况下,这些都是编译之前被替换的预处理器宏。 Note that if UPPER cannot be promoted to a float you will receive a compiler error, which is a good thing. 请注意,如果UPPER无法提升为float您将收到编译器错误,这是一件好事。 if it can be, it will be, and the printf() will find the bytes it needs to print what it wants. 如果它可以,它将是,并且printf()将找到它需要打印它想要的字节。 The same is true for int and LOWER respectively. int和LOWER也是如此。 The above printf will degenerate to this after preprocessing: 上面的printf会在预处理后退化为:

printf("%d %f", (int)0, (float)300);

Now imagine your macros were instead declared as such: 现在假设您的宏被声明为:

#define LOWER 100.0
#define UPPER 300.0

The original printf() will present as thus after preprocessing: 原始printf()将在预处理后呈现:

printf("%d %f", 100.0, 300.0);

which may seem right, but is that 100.0 float really going to be properly excised by the %d format string handler in printf() ? 这似乎是正确的,但是printf()%d格式字符串处理程序是否真的可以正确地删除100.0 float? Make sure. 确保。 Doing what we did before: 做我们以前做过的事情:

printf("%d %f", (int)LOWER, (float)UPPER);

now preprocesses to: 现在预处理到:

printf("%d %f", (int)100.0, (float)300.0);

You may get a compiler warning on the float-to-int cast, you may not. 您可能会在float-to-int转换中获得编译器警告,您可能不会。 Unless you want to roll the dice that what you're passing is sized to what is byte-size-expected by things like printf() you need to be damn-sure everything matches. 除非你想掷骰子,你传递的大小是像printf()这样的字节大小所期望的,你需要确保一切都匹配。 This can get especially frustrating when the format specifier expects one thing, something different is passed in, and yet it appears to all work fine, but only on some platforms mysteriously: 当格式说明符期望一件事,传递不同的东西时,这可能会特别令人沮丧,但它看起来一切正常,但仅在某些平台上神秘地:

printf("%ld\n", UPPER);

This may "work", but if it does it is only because a long int and a int are the same size on your platform . 这可能“有效”,但如果确实如此,那只是因为 long int int 在您的平台上具有相同的大小 Move this code to a platform where long int and int are different bit-widths and its UB all the way. 将此代码移动到一个平台,其中long intint是不同的位宽和UB的所有方式。

Bottom line: If you're passing preprocessor macros into variadic parameter lists for things like printf() that have size expectations for the data being pushed (as specified by the format string for example) you better make sure what you're pushing is what is expected. 结论:如果你将预处理器宏传递给variadic参数列表,例如printf() ,它们对推送的数据有大小期望(例如格式字符串的指定),你最好确保你所推送的是什么是期待。

It's untyped; 它是无类型的; Just look at it as a textual substitution of your source: 只需将其视为源的文本替换:

printf("%d %f", 0, 300);

#define is a preprocessor directive . #define是一个预处理程序指令 After compilation it does not exist. 编译后它不存在。 Instead the corresponding values will be replaced in the code. 而是在代码中替换相应的值。 In this case actual code that is being compiled after macro expansion is 在这种情况下,宏扩展后正在编译的实际代码是

//header stdio.h
//header stdlib.h


int main()
{
    printf("%d %f",0,300);
    return 0;
}

And yes in this case both 0,300 are integers. 是的,在这种情况下,0,300都是整数。 !

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM