我正在学习指针,并尝试进行实验! 这是我的代码。
#include<stdio.h>
int main() {
int a[2]={1,2};
int* p=a;
int* q=&a;
int *r=&a[0];
printf("%d %d %d",p,q,r);
return 0;
}
代码的输出为:
-20578720 -20578720 -20578720
现在,当我将q
更改为integer variable
时,地址不是负数:
#include<stdio.h>
int main() {
int a[2]={1,2};
int* p=a;
int q =*a;//this is the change
int *r=&a[0];
printf("%d %d %d",p,q,r);
return 0;
}
现在输出:
1822271664 1 1822271664
我尝试在网上搜索,发现了这个memory address positive or negative value in c? 它告诉使用%p ,我这样做了,我得到了正十六进制地址值:
0x7ffc4b5dbb90 0x7ffc4b5dbb90 0x7ffc4b5dbb90
现在我的答案正确了,但是不知道
对于第一个,我明白了,但我无法理解答案:Difference between %d and %p printf format string directives in c language?
答案 0 :(得分:2)
应该用%p
而不是%d
打印指针:该数字可能太大,因此溢出。
编辑
让我更清楚一点:int
char
等类型的位/字节数是固定的。即使两种类型具有相同的位数,区别也在于计算机如何解释它们。对于包括字符在内的整数,n
位可以表示2^n
个值。有符号整数使用其中一些来表示负数:特别是您可以表示-2^(n/2)
至2^(n/2) - 1
范围内的数字。相反,unsigned int表示从0
到2^n - 1
的数字。最大的整数将除msb之外的所有位都设置为1。要获得对应的正数,步骤是完全相同的
使用Two's complement计算负数:您采用正数的位表示形式,对每个位进行负运算,然后将结果加1。负数的最高有效位设置为1。
让我们考虑2位:您可以用它表示4个值。如果您使用无符号表示形式,则二进制数10
显然对应于1
。相反,如果您将其解释为带符号的数字,则其值为-2
。
另一个例子是下面的例子,例如一个8位的整数:00001011
。这是一个正数。假设将其转换为较小大小的整数类型,例如4位。根据{{3}},最常见的行为(实际上取决于实现)是丢弃最高有效位。因此,您的电话号码将变为1011
,但是使用int
表示形式,现在将其视为负数。
您可能尝试以未签名的%u
进行打印:
printf("%u %u %u",(unsigned int)(p),(unsigned int)(q),(unsigned int)(r));
还请注意,我收到警告:warning: incompatible pointer types initializing 'int *' with an expression of type 'int (*)[2]' [-Wincompatible-pointer-types]
对于
int *q = &a;
编辑
例如,在我的计算机上运行的该程序中,返回的指针大小为int
类型为8字节,int
类型为4字节:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
printf("size of int*: %lu\n", sizeof(int*));
printf("size of int: %lu\n", sizeof(int));
return 0;
}
由此看来,您正在关注我所举示例的第二种情况。
请注意:如果指针大小较大,则强制转换为unsigned int
可能还不够。
答案 1 :(得分:-1)
与将其转换为整数变量无关。 您运行了两次程序,每次将变量分配到不同的地址。
使用%d时,它将打印该值的带符号整数表示形式,但可以容纳16位或32位