如果我宣布
int x = 5 ;
int* p = &x;
unsigned int y = 10 ;
cout << p+y ;
这在C ++中是否有效,如果没有,为什么?
没有实际用途,但有可能吗?
答案 0 :(得分:4)
数学有效;结果指针不是。
当您说ptr + i
(其中ptr
是int*
)时,评估为i * sizeof(int)
个字节超过ptr
的int的地址。在这种情况下,由于你的指针指向单个int而不是它们的数组,你不知道(并且C ++没有说)p+10
处的内容。
但是,如果您有类似
的内容int ii[20] = { 0 };
int *p = ii;
unsigned int y = 10;
cout << p + y;
然后你有一个你可以实际使用的指针,因为它仍然指向它最初指向的数组中的某个位置。
答案 1 :(得分:3)
您在代码段中执行的操作不是将unsigned int转换为指针。相反,您正在通过整数偏移量递增指针,这是完全有效的事情。当您访问数组的索引时,您基本上将指针指向第一个元素并将其增加整数索引值。此操作的结果是另一个指针。
如果p是指针/数组,则以下两行是等效且有效的(假设指向数组足够大)
p[5] = 1;
*(p + 5) = 1;
要将unsigned int转换为指针,必须使用强制转换
unsigned int i = 5;
char *p = reinterpret_cast<char *>(i);
然而这很危险。你怎么知道5是一个有效的地址?
指针在内存中表示为无符号整数类型,即地址。您可以将指针存储在整数中。但是,必须注意整数数据类型足够大以容纳指针中的所有位。如果unsigned int为32位且指针为64位,则某些地址信息将丢失。
C ++ 11引入了一种新类型uintptr_t
,它保证足够大以容纳指针。因此,可以安全地将指针转换为uintptr_t
并再次返回。
您需要以整数存储指针,这是非常罕见的(绝不应该是普通的编程)。
但是,通过整数偏移修改指针是完全有效和常见的。
答案 2 :(得分:0)
类型int
的变量是能够包含整数值的变量。 int*
类型的变量是包含整数值的变量copable的指针。
每个指针类型都具有相同的大小并包含相同的内容:一个内存地址,32位arquitectures的大小为4个字节,64位arquitectures的大小为8个字节。它们的区别在于它们 poiting to 的变量类型。
指针对于解决在运行时动态分配的缓冲区和结构或者要使用的任何类型的变量非常有用,但存储在其他地方,您必须告诉。
使用指针进行算术运算是可能的,但它们不会按照您的想法进行。例如,将+ 1
与int
类型的指针相加会使其值增加sizeof(int)
,而不是字面1
,因为它是一个指针,这里的逻辑是你想要这个数组的下一个对象。
例如:
int a[] = { 10, 20, 30, 40 };
int *b = a;
printf("%d\n", *b);
b = b + 1;
printf("%d\n", *b);
将输出:
10
20
因为b
指向整数值10
,并且当它与1
求和,或者包含整数的任何变量时,它随后会对下一个值{{{ 1}}。
如果要使用存储在20
的变量执行操作,可以使用:
b
现在*b = *b + 3;
是相同的指针,地址没有改变。但数组b
现在包含值10, 20, 30, 40
,因为您13, 20, 30, 40
增加了元素b
正在等待。
答案 3 :(得分:0)
这在c ++中是否有效,如果不是为什么?
是。 cout << p+y;
有效,因为您可以看到尝试编译它。实际上p+y
非常有效,*(p+y)
可以转换为p[y]
,用于C风格的数组(不是我建议在C ++中使用它)。
有效并不意味着它实际上有意义或者结果指针有效。由于p
指向int,因此结果指针将是sizeof(int) * 10
与x
位置的偏移量。你不确定那里有什么。