简体   繁体   English

float指针和int指针地址有什么区别?

[英]What is the difference between float pointer and int pointer address?

I tried to run this code, 我试着运行这段代码,

int *p;
float q;
q = 6.6;
p = &q;

Though it will be a warning, but i think &q and p are of same size, so p can have an address of q . 虽然这将是一个警告,但我认为&qp具有相同的大小,所以p可以具有q的地址。 But when I print &q and p I am getting different output. 但是当我打印&qp我得到不同的输出。 This is my output 这是我的输出

*p =  6.600000 
 q = 0.000000, p = 0x40d33333, &q = 0x7fffe2fa3c8c 

What is that I am missing? 我错过了什么? And p and &q is 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);
}

You need to take compiler warnings more seriously. 您需要更严肃地对待编译器警告。

C doesn't require compilers to reject invalid programs, it merely requires "diagnostics" for rule violations. C不要求编译器拒绝无效程序,它只需要“诊断”来规则违规。 A diagnostic can be either a fatal error message or a warning. 诊断可以是致命错误消息或警告。

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) . 它应该是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 quite that simple, but that's close enough.) (这不是那么简单,不过这也够近。)

int *p;
float q;
q = 6.6;

That's ok. 没关系。

p = &q;

p is of type int* ; p的类型为int* ; &q is of type float* . &q的类型为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. 看待它的最简单方法是它完全是非法的。

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. 但这样做的理由很少。 p is a pointer to int ; p是指向int的指针; it should point to an int object unless you have a very good reason to make it point to something else. 它应该指向一个int ,除非你有一个很好的理由,使其指向别的对象。 In some circumstances, the conversion itself can have undefined behavior. 在某些情况下,转换本身可能具有未定义的行为。

printf("*p =  %f \n q = %f, p = %p, &q = %p \n",*p,q,p,&q);

The %f format requires a double argument (a float argument is promoted to double in this context so float would be ok). %f格式需要一个double参数(在此上下文中float参数被提升为double ,因此float可以正常)。 But *p is of type int . *p的类型为int Calling printf with an argument of the wrong type causes your program's behavior to be undefined. 使用错误类型的参数调用printf会导致程序的行为未定义。

%p requires an argument of type void* , not just of any pointer type. %p需要类型为void*的参数,而不仅仅是任何指针类型的参数。 If you want to print a pointer value, you should cast it to void* : 如果要打印指针值,则应将其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. 至于标题中的问题, int*float*类型的指针有不同的类型。 An int* should point to an int object; int*应该指向一个int对象; a float* should point to a float object. float*应该指向一个float对象。 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. 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 int object (if it's not a null pointer). 如果声明int*类型的对象,则表示您打算将其指向int对象(如果它不是空指针)。 Storing the address of a float object in your int* object is almost certainly a mistake. int*对象中存储float对象的地址几乎肯定是一个错误。 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). 强制类型安全允许尽早检测到此类错误(当您的编译器打印警告时,而不是在重要客户端的演示期间程序崩溃时)。

It's likely (but not guaranteed) that int* and float* are the same size and have the same internal representation. 可能(但不保证) int*float*具有相同的大小并具有相同的内部表示。 But the meaning of an int* object is not "a collection of 32 (or 64) bits containing a virtual address", but "something that points to an int object". 但是int*对象的含义不是“包含虚拟地址的32(或64)位的集合”,而是“指向int对象的东西”。

You're getting undefined behaviour, because you're passing the wrong types to printf . 您将获得未定义的行为,因为您将错误的类型传递给printf When you tell it to expect a float, it actually expects a double - but you pass an int . 当你告诉它期望浮动时,它实际上需要一个double - 但你传递一个int

As a result it prints the wrong information, because printf relies entirely on the format string to access the arguments you pass it. 因此,它会输出错误的信息,因为printf完全依赖于格式字符串来访问您传递它的参数。

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 p is going to point to an integer. 在这种情况下,我们向编译器指出p将指向一个整数。 So it is known that when we do something like *p , at runtime, the no. 所以众所周知,当我们在运行时执行类似*p的操作时,不会。 of bytes equal to size of an int would be read. 将读取等于int大小的字节数。

If you assign address of a datatype occupying x number 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 ,则在使用间接运算符时读取错误的字节数。

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

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