If I declare
int x = 5 ;
int* p = &x;
unsigned int y = 10 ;
cout << p+y ;
Is this a valid thing to do in C++, and if not, why?
It has no practical use, but is it possible?
数学是有效的;结果指针不是。
当你说ptr + i
(where ptr
is an ) 时,它的计算结果是一个字节过去int*
的 int 的地址 。在这种情况下,由于您的指针指向单个 int 而不是它们的数组,因此您不知道(并且 C++ 没有说)在.i * sizeof(int)
ptr
p+10
但是,如果你有类似的东西
int ii[20] = { 0 };
int *p = ii;
unsigned int y = 10;
cout << p + y;
然后你会有一个你可以实际使用的指针,因为它仍然指向它最初指向的数组中的某个位置。
您在代码片段中所做的不是将 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
再次转换指针。
您需要将指针存储在整数中是非常罕见的(不应该在普通编程中使用)。
但是,通过整数偏移量修改指针是完全有效且常见的。
类型int
变量是能够包含整数值的变量。类型变量int*
是指向可包含整数值的变量的指针。
每个指针类型都具有相同的大小并包含相同的内容:一个内存地址,对于 32 位架构,其大小为 4 个字节,对于 64 位架构,其大小为 8 个字节。它们的区别在于它们指向的变量的类型。
指针对于寻址在运行时动态分配的缓冲区和结构或任何类型的要使用但存储在其他地方的变量很有用,您必须知道在哪里。
可以使用指针进行算术运算,但它们不会按照您的想法进行。例如,对+ 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
时,或者任何包含整数的变量,它就会指向下一个值,20
。
如果要对存储在 的变量b
执行操作,可以使用:
*b = *b + 3;
现在b
是同一个指针,地址没有改变。但是数组10, 20, 30, 40
现在包含值13, 20, 30, 40
,因为您增加了指向的元素b
3
。
这是在 c++ 中做的有效的事情,如果不是,为什么?
是的。正如您在尝试编译它时看到的那样cout << p+y;
是有效的。实际上p+y
是如此有效,*(p+y)
可以翻译成p[y]
在 C 样式数组中使用的(不是我建议在 C++ 中使用它)。
有效并不意味着它实际上有意义或结果指针是有效的。由于p
指向 int ,因此结果指针将是sizeof(int) * 10
从 的位置的偏移量x
。而且你不确定里面有什么。