C语言 浮点指针和 int 指针地址有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15790980/
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
What is the difference between float pointer and int pointer address?
提问by Rohit O
I tried to run this code,
我试图运行这段代码,
int *p;
float q;
q = 6.6;
p = &q;
Though it will be a warning, but i think &qand pare of same size, so pcan have an address of q. But when I print &qand pI am getting different output.
This is my output
虽然这将是一个警告,但我认为&q和p大小相同的,所以p可以有一个地址q。但是当我打印时&q,p我得到了不同的输出。这是我的输出
*p = 6.600000
q = 0.000000, p = 0x40d33333, &q = 0x7fffe2fa3c8c
What is that I am missing?
And pand &qis same when both pointer and variable type is same.
我错过了什么?和p和&q是相同的当两个指针和变量类型是一样的。
My complete code is
我的完整代码是
#include<stdio.h>
void main()
{
int *p;
float q;
q = 6.6;
p = &q;
printf("*p = %f \n q = %f, p = %p, &q = %p \n",*p,q,p,&q);
}
回答by Keith Thompson
You need to take compiler warnings more seriously.
您需要更认真地对待编译器警告。
C doesn't require compilers to rejectinvalid programs, it merely requires "diagnostics" for rule violations. A diagnostic can be either a fatal error message or a warning.
C 不要求编译器拒绝无效程序,它只需要对违反规则的“诊断”。诊断可以是致命错误消息或警告。
Unfortunately, it's common for compilers to issue warnings for assignments of incompatible pointer types.
不幸的是,编译器通常会针对不兼容的指针类型的赋值发出警告。
void main()
This is wrong; it should be int main(void). Your compiler may let you get away with it, and it may not cause any visible problems, but there's no point in not writing it correctly. (It's not quitethat simple, but that's close enough.)
这是错误的;应该是int main(void)。您的编译器可能会让您逍遥法外,它可能不会导致任何可见的问题,但没有正确编写它是没有意义的。(这不是很简单,但是这足够接近。)
int *p;
float q;
q = 6.6;
That's ok.
没关系。
p = &q;
pis of type int*; &qis of type float*. Assigning one to the other (without a cast) is a constraint violation. The simplest way to look at it is that it's simply illegal.
p是类型int*; &q是 类型float*。将一个分配给另一个(没有强制转换)是违反约束的。最简单的看待它的方法是它完全是非法的。
If you really want to do this assignment, you can use a cast:
如果你真的想做这个任务,你可以使用演员表:
p = (int*)&q; /* legal, but ugly */
but there's rarely a good reason to do so. pis a pointer to int; it should point to an intobject unless you have a verygood reason to make it point to something else. In some circumstances, the conversion itself can have undefined behavior.
但很少有充分的理由这样做。 p是一个指向int; 应该指出的int,除非你有一个对象非常充分的理由,使其指向别的东西。在某些情况下,转换本身可能具有未定义的行为。
printf("*p = %f \n q = %f, p = %p, &q = %p \n",*p,q,p,&q);
The %fformat requires a doubleargument (a floatargument is promoted to doublein this context so floatwould be ok). But *pis of type int. Calling printfwith an argument of the wrong type causes your program's behavior to be undefined.
该%f格式需要一个double参数(在此上下文中将float参数提升为一个参数double,因此float可以)。但*p属于int. printf使用错误类型的参数调用会导致程序的行为未定义。
%prequires an argument of type void*, not just of any pointer type. If you want to print a pointer value, you should cast it to void*:
%p需要一个 type 参数void*,而不仅仅是任何指针类型。如果你想打印一个指针值,你应该将它转换为void*:
printf("&q = %p\n", (void*)&q);
It's likely to work without the cast, but again, the behavior is undefined.
它可能在没有演员的情况下工作,但同样,行为是未定义的。
If you get any warnings when you compile a program, don't even bother running it. Fix the warnings first.
如果在编译程序时收到任何警告,请不要运行它。首先修复警告。
As for the question in your title, pointers of type int*and float*are of different types. An int*should point to an intobject; a float*should point to a floatobject. Your compiler may let you mix them, but the result of doing so is either implementation-defined or undefined. The C language, and particularly many C compilers, will let you get away with a lot of things that don't make much sense.
至于你标题中的问题,指针类型int*和float*是不同类型的。一个int*应该指向一个int对象;afloat*应该指向一个float对象。您的编译器可能会让您混合使用它们,但这样做的结果要么是实现定义的,要么是未定义的。C 语言,尤其是许多 C 编译器,会让您摆脱很多没有多大意义的事情。
The reason that they're distinct types is to (try to) prevent, or at least detect, errors in their use. If you declare an object of type int*, you're saying that you intend for it to point to an intobject (if it's not a null pointer). Storing the address of a floatobject in your int*object is almost certainly a mistake. Enforcing type safety allows such mistakes to be detected as early as possible (when your compiler prints a warning rather than when your program crashes during a demo for an important client).
它们是不同类型的原因是(尝试)防止或至少检测它们的使用错误。如果你声明一个 type 的对象int*,你是说你打算让它指向一个int对象(如果它不是一个空指针)。将float对象的地址存储在您的int*对象中几乎肯定是一个错误。强制类型安全允许尽早检测到此类错误(当您的编译器打印警告时,而不是在重要客户的演示期间您的程序崩溃时)。
It's likely (but not guaranteed) that int*and float*are the same size and have the same internal representation. But the meaningof an int*object is not "a collection of 32 (or 64) bits containing a virtual address", but "something that points to an intobject".
很可能(但不能保证)int*和float*具有相同的大小并具有相同的内部表示。但含义一个的int*对象不是“包含虚拟地址32(或64)位的集合”,但“的东西,指向一个int对象”。
回答by teppic
You're getting undefined behaviour, because you're passing the wrong types to printf. When you tell it to expect a float, it actually expects a double- but you pass an int.
你得到了未定义的行为,因为你将错误的类型传递给printf. 当你告诉它期望一个浮点数时,它实际上期望一个double- 但你传递了一个int.
As a result it prints the wrong information, because printfrelies entirely on the format string to access the arguments you pass it.
结果它打印了错误的信息,因为printf完全依赖于格式字符串来访问您传递给它的参数。
回答by Suvarna Pattayil
In addition to what is said by teppic,
除了 teppic 所说的,
Consider,
考虑,
int a = 5;
int *p = &a;
In this case we indicate to the compiler that pis going to point to an integer. So it is known that when we do something like *p, at runtime, the no. of bytes equal to size of an intwould be read.
在这种情况下,我们向编译器指示p将指向一个整数。所以众所周知,当我们*p在运行时做类似的事情时,没有。int将读取等于大小的字节数。
If you assign address of a datatype occupying xnumber of bytes to a pointer of which is declared to hold the address of datatypes of fewer bytes than x, you read the wrong number of bytes when using the indirection operator.
如果将占用x字节数的数据类型的地址分配给声明为保存字节数少于 的数据类型地址的指针,则x在使用间接运算符时会读取错误的字节数。

