我目前正在学习指针,但我几乎没有问题:
当我们说OSError, err:
时,编译器会为指针int a[] = {10, 11}; int *p = a
(指向数组的第一个地址)分配内存。但是如果我们说p
,这是否意味着某些内存已经被一个名为p + 1
的新指针初始化了?
如果上述答案为否定,即没有为p + 1
分配内存:当我们使用p + 1
时,我们仍然可以获得值*(p + 1)
。这是否意味着可以在没有指针的情况下使用此符号11
(只要我们知道地址)?
答案 0 :(得分:5)
是的,*
可以在没有指针变量的情况下使用,它只是一个运算符。它需要应用于指针类型的表达式,但该表达式不必是单个变量名。
例如:
int x = 42;
*(&x) = 4711;
以上使用x
运算符将4711
设置为*
,但代码中没有单独的指针变量。 &x
返回的值的类型当然是int *
,即"指向整数"的指针,以及*
可以与p + 1
一起使用的类型
表达式assertResult
只是一个表达式,可以对其进行求值,结果可以使用(或丢弃,具体取决于上下文)。它不是"指针",虽然结果值是表达式本身不是指针。
答案 1 :(得分:2)
1)当我们说
int a[] = {10, 11}; int *p = a;
时,内存会为指针p
分配内存(指向数组的第一个地址),但如果我们说p + 1
,那是否意味着内存已启动一个名为p + 1
的新指针?
记忆被分配' (不一定来自RAM)但它没有给出名称 - 它是一个未命名的临时值。它可能只存在于CPU
寄存器中。
2)如果上述答案为否定,则内存不会为
p + 1
分配内存,当我们使用*(p + 1)
时,我们仍然可以获得值11
,这是否意味着这个符号*
可以在没有指针的情况下使用(只要我们知道地址)?
创建临时指针,*(p + 1)
解除引用。
答案 2 :(得分:2)
我们假设有声明
int a[] = {10, 11};
int *p = a;
在这种情况下,变量P
由数组a
的第一个元素的地址初始化。
评估此表达式
p + 1
编译器获取存储在指针p
中的值,并根据指针算法将表达式sizeof( int )
的值添加到其中。因此,表达式产生一个新地址,该地址指向数组a
的第一个元素之后的内存,该数组是计算值,是数组第二个元素的地址。
实际上,编译器可以创建类型为int *
的临时对象来存储此中间值。但是对象的生命周期不会超过表达式本身的生命周期。
您可以将operator *
应用于具有指针类型的表达式。
考虑这段代码
int a[] = {10, 11};
int *p = a;
for ( size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++ )
{
std::cout << *( p + i ) >> ' ';
}
std::cout << std::endl;
至于这个表达
p++;
然后有两个动作。第一个产生表达式的值,该值等于存储在p中的当前值。第二个相当于p = p + 1;
。
答案 3 :(得分:1)
内存将分配内存
编译器会生成代替内存的代码。当您声明int* p;
然后在代码中的某处使用变量p
时会发生这种情况。无论你如何使用它。
这是否意味着这个符号*可以在没有指针的情况下使用(只要我们知道地址)
这个问题没有任何意义。如果没有指针操作数,你究竟会如何使用*
?
不太确定你想做什么。要获取存储在已知地址的内容,您必须具有指针类型,并且必须使用*
运算符。
所以从理论上讲,你可以做一些愚蠢的事情,比如
*(int*)(0x12345678 + 1*sizeof(int))
或等效的
((int*)0x12345678)[1]
如果您知道该数组存储在地址0x12345678。但实际上,你永远不会编写这样的代码,因为它很丑陋而且地址可能会改变。