结构的printf?(C/C++, VC2008)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4081491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Printf for struct? (C/C++, VC2008)
提问by k06a
Just build&run this in VC2008:
只需在 VC2008 中构建和运行它:
struct A
{
int a;
int b;
int c;
};
A a = { 10, 20, 30 };
printf("%d %d %d\n", a);
Is it normal?
正常吗?
10 20 30
I'd like to cast! but it don't works:
我想投!但它不起作用:
struct A
{
int a;
int b;
int c;
operator int()
{
return a + b + c;
}
};
A a = { 10, 20, 30 };
printf("%d\n", a);
output is only:
输出仅为:
10
I need auto-casting for template-utility. Here it is: https://code.google.com/p/boolib/source/browse/boolib/crypt/ShakedValue.hIt should hide in memory value, that any hack-programms (ArtMoney) can't find value.
我需要模板实用程序的自动转换。它是:https://code.google.com/p/boolib/source/browse/boolib/crypt/ShakedValue.h它应该隐藏在内存值中,任何黑客程序(ArtMoney)都找不到值。
And one more trick usage: Print private members of the struct/class
还有一个技巧用法:打印结构/类的私有成员
回答by Blindy
If you want a cast, then cast it:
如果你想要一个演员,那么演员:
struct A
{
int a;
int b;
int c;
operator int()
{
return a + b + c;
}
};
A a = { 10, 20, 30 };
printf("%d\n", (int)a);
the output will be
输出将是
60
回答by Fred Foo
It's undefined behavior, so in a certain sense every possible behavior can be termed "normal" for this function call. It can be explained though.
这是未定义的行为,因此在某种意义上,对于此函数调用,每个可能的行为都可以称为“正常”。不过也可以解释。
printf
takes a variable number of arguments after the format string. How these are packed is left to the implementation. It seems that Visual C++ packs the arguments in memory the same way it packs the members of your struct A
, so every time it calls va_arg
internally, it gets the next element in a
.
printf
在格式字符串后接受可变数量的参数。这些如何打包留给实现。看来,VISUAL C ++包的参数在内存中包你的成员以同样的方式struct A
,所以它调用的每个时间va_arg
内,它会在未来的元素a
。
As regards the casting, you can't rely on autocasting in a varargs context, since the optional parameters have no type. printf
is declared as int printf(char const *, ...)
. ...
is a range of untyped parameters.
至于转换,您不能依赖可变参数上下文中的自动转换,因为可选参数没有类型。printf
被声明为int printf(char const *, ...)
. ...
是一系列无类型参数。
回答by Jens Gustedt
There is no such thing like C/C++, your code is just a mixture of the two. In particular it doesn't compile with a standard C compiler because you are missing the struct
keyword in the declaration of a
.
没有像 C/C++ 这样的东西,你的代码只是两者的混合。特别是它不能使用标准 C 编译器进行编译,因为您struct
在a
.
For your use of printf
. First of all you shouldn't if this is C++. It has its own mechanisms for IO. Use them.
供您使用printf
。首先,如果这是 C++,你不应该这样做。它有自己的IO机制。使用它们。
Then placing a structure as an argument in a ...
list is undefined behavior. You just had bad luck, and the compiler did what it did. It could just have sad "no, no, don't do that", or at least have given you a warning.
然后将结构作为参数放置在...
列表中是未定义的行为。你只是运气不好,编译器做了它所做的。它可能只是悲伤的“不,不,不要那样做”,或者至少给了你一个警告。
回答by DevSolar
You placed three integers on the stack, and then retrieved three integers (one per "%d"). Yes, it is normal - but in the realm of "really uglyhack" (and Undefined Behaviour to boot, as plinth correctly commented).
您将三个整数放在堆栈上,然后检索了三个整数(每个“%d”一个)。是的,这是正常的 - 但在“非常丑陋的黑客”领域(以及要启动的未定义行为,正如底座正确评论的那样)。
回答by Steve Townsend
This works by accident. Most times when your printf
arg count or types do not match the results will not be pretty.
这是偶然的。大多数情况下,当您的printf
arg 计数或类型不匹配时,结果不会很漂亮。
If you want C++ use ostream/cout
如果你想要 C++ 使用 ostream/cout
std::cout << a.a << ' ' << a.b << ' ' << a.c << std::endl;
If you want non-brittle C code use:
如果您想要非脆弱的 C 代码,请使用:
printf("%d %d %d\n", a.a, a.b, a.c);
回答by Doug T.
There's a lot of compiler/environment dependent stuff in how printf might behave.
printf 的行为方式与编译器/环境相关的内容很多。
printf ostensibly uses C's var args features where when you have a declaration
printf 表面上使用 C 的 var args 功能,当您有声明时
int printf(char* formatStr, ...)
you can pass multiple arguments in the "...". Then in the body of printf you would do something like the following
您可以在“...”中传递多个参数。然后在 printf 的正文中,您将执行以下操作
// count how many formatters are in the format string
// and calculate "amount"
// here amount = 3
va_list valsToPrint;
va_start(valsToPrint,amount);
for (int i = 0; i < amount; ++i)
{
// treat each value as a 32-bit int and print it
}
va_end(vl);
The important thing is -- there's a lot of compiler/environment dependent stuff in here. Such as the fact that the struct is probably packed so that each value shows up on 32-bit boundaries and how the va_list is actually determined from the compiler. I imagine compiler-to-compiler there could be some very different behavior from your code, but its not entirely surprising that exhibits the behavior you describe.
重要的是——这里有很多编译器/环境相关的东西。例如,结构可能被打包,以便每个值都显示在 32 位边界上,以及 va_list 是如何从编译器中实际确定的。我想编译器到编译器可能会有一些与您的代码非常不同的行为,但展示您描述的行为并不完全令人惊讶。
回答by Preet Sangha
it's because of memory layout of the struct. the ints are straight after each other. so putting the struct in the printf call is basically putiing the same as putting each one on one after the other
这是因为结构的内存布局。整数是相互直接的。因此,将结构体放入 printf 调用中基本上与将每个结构体一个接一个地放置相同
回答by Lavir the Whiolet
printf() has "(char *, ...)" signature. That means it is up to "printf" function to handle all arguments after "char *".
printf() 具有“(char *, ...)”签名。这意味着由“printf”函数来处理“char *”之后的所有参数。
You pass a struct A to printf(). In memory it has following layout: "int, int, int". printf() function reads format string ("%d %d %d") and "thinks" that you passed 3 integers to it. And this "assumption" coincides with the struct's layout. So it prints all its fields as separate values.
您将结构 A 传递给 printf()。在内存中,它具有以下布局:“int,int,int”。printf() 函数读取格式字符串 ("%d %d %d") 并“认为”您向它传递了 3 个整数。而这个“假设”与结构的布局相吻合。因此它将所有字段打印为单独的值。
Try to remove "b" field and you will see that printf() will print values of "a" field, "c" field and SEGMENTATION FAULT.
尝试删除“b”字段,您将看到 printf() 将打印“a”字段、“c”字段和SEGMENTATION FAULT 的值。