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
. But when I print &q
and p
I 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 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);
}
3 个解决方案
#1
8
You need to take compiler warnings more seriously.
您需要更严肃地对待编译器警告。
C doesn't require compilers to reject invalid 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 quite that simple, but that's close enough.)
这是错的;它应该是int main(void)。您的编译器可能会让您逃脱它,并且它可能不会导致任何明显的问题,但是没有正确编写它没有意义。 (它不是那么简单,但那已足够接近了。)
int *p;
float q;
q = 6.6;
That's ok.
p = &q;
p
is of type int*
; &q
is 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. p
is a pointer to int
; it should point to an int
object unless you have a very good 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 %f
format requires a double
argument (a float
argument is promoted to double
in this context so float
would be ok). But *p
is of type int
. Calling printf
with an argument of the wrong type causes your program's behavior to be undefined.
%f格式需要一个double参数(在此上下文中float参数被提升为double,因此float可以正常)。但* p的类型为int。使用错误类型的参数调用printf会导致程序的行为未定义。
%p
requires 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需要类型为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 int
object; a float*
should point to a float
object. 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对象; 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 int
object (if it's not a null pointer). Storing the address of a float
object 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).
它们是不同类型的原因是(试图)防止或至少检测其使用中的错误。如果声明int *类型的对象,则表示您打算将其指向int对象(如果它不是空指针)。在int *对象中存储float对象的地址几乎肯定是一个错误。强制类型安全性允许尽早检测到此类错误(当您的编译器打印警告时,而不是在重要客户端的演示期间程序崩溃时)。
It's likely (but not guaranteed) that int*
and float*
are the same size and have the same internal representation. 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 *和float *具有相同的大小并且具有相同的内部表示。但是int *对象的含义不是“包含虚拟地址的32(或64)位的集合”,而是“指向int对象的东西”。
#2
8
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。当你告诉它期望浮动时,它实际上需要一个双 - 但你传递一个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完全依赖于格式字符串来访问传递它的参数。
#3
0
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. So it is known that when we do something like *p
, at runtime, the no. of bytes equal to size of an int
would be read.
在这种情况下,我们向编译器指出p将指向一个整数。所以众所周知,当我们在运行时执行类似* p的操作时,不会。将读取等于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少的字节数据类型的地址,则在使用间接运算符时会读取错误的字节数。
#1
8
You need to take compiler warnings more seriously.
您需要更严肃地对待编译器警告。
C doesn't require compilers to reject invalid 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 quite that simple, but that's close enough.)
这是错的;它应该是int main(void)。您的编译器可能会让您逃脱它,并且它可能不会导致任何明显的问题,但是没有正确编写它没有意义。 (它不是那么简单,但那已足够接近了。)
int *p;
float q;
q = 6.6;
That's ok.
p = &q;
p
is of type int*
; &q
is 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. p
is a pointer to int
; it should point to an int
object unless you have a very good 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 %f
format requires a double
argument (a float
argument is promoted to double
in this context so float
would be ok). But *p
is of type int
. Calling printf
with an argument of the wrong type causes your program's behavior to be undefined.
%f格式需要一个double参数(在此上下文中float参数被提升为double,因此float可以正常)。但* p的类型为int。使用错误类型的参数调用printf会导致程序的行为未定义。
%p
requires 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需要类型为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 int
object; a float*
should point to a float
object. 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对象; 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 int
object (if it's not a null pointer). Storing the address of a float
object 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).
它们是不同类型的原因是(试图)防止或至少检测其使用中的错误。如果声明int *类型的对象,则表示您打算将其指向int对象(如果它不是空指针)。在int *对象中存储float对象的地址几乎肯定是一个错误。强制类型安全性允许尽早检测到此类错误(当您的编译器打印警告时,而不是在重要客户端的演示期间程序崩溃时)。
It's likely (but not guaranteed) that int*
and float*
are the same size and have the same internal representation. 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 *和float *具有相同的大小并且具有相同的内部表示。但是int *对象的含义不是“包含虚拟地址的32(或64)位的集合”,而是“指向int对象的东西”。
#2
8
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。当你告诉它期望浮动时,它实际上需要一个双 - 但你传递一个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完全依赖于格式字符串来访问传递它的参数。
#3
0
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. So it is known that when we do something like *p
, at runtime, the no. of bytes equal to size of an int
would be read.
在这种情况下,我们向编译器指出p将指向一个整数。所以众所周知,当我们在运行时执行类似* p的操作时,不会。将读取等于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少的字节数据类型的地址,则在使用间接运算符时会读取错误的字节数。