结构体的Printf? (C/C++,VC2008)
在 VC2008 中构建并运行这个:
struct A
{
int a;
int b;
int c;
};
A a = { 10, 20, 30 };
printf("%d %d %d\n", a);
正常吗?
10 20 30
我想投!但它不起作用:
struct A
{
int a;
int b;
int c;
operator int()
{
return a + b + c;
}
};
A a = { 10, 20, 30 };
printf("%d\n", a);
输出只是:
10
我需要模板实用程序的自动转换。 这是:https://code.google.com /p/boolib/source/browse/boolib/crypt/ShakedValue.h 它应该隐藏在内存值中,任何黑客程序(ArtMoney)都无法找到值。
还有一个技巧用法:打印结构/类的私有成员
Just build&run this in 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.h
It should hide in memory value, that any hack-programms (ArtMoney) can't find value.
And one more trick usage: Print private members of the struct/class
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果你想要强制转换,那就强制转换:
输出将是
If you want a cast, then cast it:
the output will be
这是未定义的行为,因此在某种意义上,对于此函数调用,每种可能的行为都可以称为“正常”。不过可以解释一下。
printf
在格式字符串之后接受可变数量的参数。如何打包这些内容留给实现。看来 Visual C++ 将参数打包在内存中的方式与打包struct A
的成员的方式相同,因此每次它在内部调用va_arg
时,它都会获取下一个元素一个
。至于转换,您不能依赖可变参数上下文中的自动转换,因为可选参数没有类型。
printf
声明为int printf(char const *, ...)
。...
是一系列无类型参数。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 yourstruct A
, so every time it callsva_arg
internally, it gets the next element ina
.As regards the casting, you can't rely on autocasting in a varargs context, since the optional parameters have no type.
printf
is declared asint printf(char const *, ...)
....
is a range of untyped parameters.不存在像 C/C++ 这样的东西,你的代码只是两者的混合。特别是它不能使用标准 C 编译器进行编译,因为您在
a
声明中缺少struct
关键字。供您使用
printf
。首先,如果这是 C++,你不应该这样做。它有自己的IO机制。使用它们。然后将结构作为参数放入
...
列表中是未定义的行为。你只是运气不好,编译器做了它所做的事情。它可能只是悲伤地“不,不,不要这样做”,或者至少给了你一个警告。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 ofa
.For your use of
printf
. First of all you shouldn't if this is C++. It has its own mechanisms for IO. Use them.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.您将三个整数放入堆栈,然后检索三个整数(每个“%d”一个)。是的,这是正常的 - 但在“真正丑陋黑客”领域(以及未定义的行为启动,正如底座正确评论的那样)。
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 ugly hack" (and Undefined Behaviour to boot, as plinth correctly commented).
这是偶然发生的。大多数时候,当您的
printf
参数计数或类型不匹配时,结果不会很漂亮。如果您想要 C++,请使用
ostream/cout
如果您想要非脆弱的 C 代码,请使用:
This works by accident. Most times when your
printf
arg count or types do not match the results will not be pretty.If you want C++ use
ostream/cout
If you want non-brittle C code use:
这是因为结构的内存布局。整数是紧接着彼此的。因此,将结构放入 printf 调用中基本上与将每个结构体依次放入相同的位置
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 的行为方式有很多依赖于编译器/环境的内容。
printf 表面上使用 C 的 var args 功能,当您有声明时,
您可以在“...”中传递多个参数。然后在 printf 的主体中,您将执行如下所示的操作。
重要的是 - 这里有很多依赖于编译器/环境的内容。例如,该结构可能已打包,以便每个值都显示在 32 位边界上,以及 va_list 是如何由编译器实际确定的。我想编译器到编译器可能会出现一些与您的代码非常不同的行为,但表现出您所描述的行为并不完全令人惊讶。
There's a lot of compiler/environment dependent stuff in how printf might behave.
printf ostensibly uses C's var args features where when you have a declaration
you can pass multiple arguments in the "...". Then in the body of printf you would do something like the following
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.
printf() 具有“(char *, ...)”签名。这意味着由“printf”函数来处理“char *”之后的所有参数。
您将结构体 A 传递给 printf()。在内存中它具有以下布局:“int,int,int”。 printf() 函数读取格式字符串(“%d %d %d”)并“认为”您向其传递了 3 个整数。这个“假设”与结构的布局一致。因此它将所有字段打印为单独的值。
尝试删除“b”字段,您将看到 printf() 将打印“a”字段、“c”字段和SEGMENTATION FAULT的值。
printf() has "(char *, ...)" signature. That means it is up to "printf" function to handle all arguments after "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.
Try to remove "b" field and you will see that printf() will print values of "a" field, "c" field and SEGMENTATION FAULT.