C++ 指针:p++&p+1

C++ 指针:p++&p+1,c++,c,pointers,C++,C,Pointers,我目前是学习指导者,但我有几个问题: 当我们说int a[]={10,11};int*p=a,编译器将为指向数组第一个地址的指针p分配内存。但是如果我们说p+1,这是否意味着一些内存已经用一个名为p+1的新指针初始化了 如果上面的答案是否定的,即没有为p+1分配内存:当我们使用*p+1时,我们仍然可以得到值11。这是否意味着只要我们知道地址,这个符号*就可以不用指针使用 是的,*可以在没有指针变量的情况下使用,它只是一个运算符。它需要应用于指针类型的表达式,但该表达式不必是单个变量名 例如: i

我目前是学习指导者,但我有几个问题:

当我们说int a[]={10,11};int*p=a,编译器将为指向数组第一个地址的指针p分配内存。但是如果我们说p+1,这是否意味着一些内存已经用一个名为p+1的新指针初始化了

如果上面的答案是否定的,即没有为p+1分配内存:当我们使用*p+1时,我们仍然可以得到值11。这是否意味着只要我们知道地址,这个符号*就可以不用指针使用

是的,*可以在没有指针变量的情况下使用,它只是一个运算符。它需要应用于指针类型的表达式,但该表达式不必是单个变量名

例如:

int x = 42;

*(&x) = 4711;
上面使用*运算符将x设置为4711,但代码中没有单独的指针变量。&x返回的值的类型当然是int*,也就是指向整数的指针,这是一种*可以与一起使用的类型

表达式p+1只是一个表达式,可以对其求值,也可以根据上下文使用或丢弃结果。它不是指针,尽管结果值是指针,但表达式本身不是。

是,*可以在没有指针变量的情况下使用,它只是一个运算符。它需要应用于指针类型的表达式,但该表达式不必是单个变量名

例如:

int x = 42;

*(&x) = 4711;
上面使用*运算符将x设置为4711,但代码中没有单独的指针变量。&x返回的值的类型当然是int*,也就是指向整数的指针,这是一种*可以与一起使用的类型

表达式p+1只是一个表达式,可以对其求值,也可以根据上下文使用或丢弃结果。它不是指针,尽管结果值是指针,但表达式本身不是

1当我们说int a[]={10,11};int*p=a;,内存会为指向数组第一个地址的指针p点分配内存,但如果我们说p+1,这是否意味着内存已经启动了一个名为p+1的新指针

内存是“分配”的,不一定来自RAM,但它没有给出名称-它是一个未命名的临时值。它可能只存在于CPU寄存器中

2如果上面的答案是否定的,那么内存没有为p+1分配内存,当我们使用*p+1时,我们仍然可以得到值11,这是否意味着只要我们知道地址,这个符号*就可以在没有指针的情况下使用

将创建一个临时指针,用于*p+1解引用

1当我们说int a[]={10,11};int*p=a;,内存会为指向数组第一个地址的指针p点分配内存,但如果我们说p+1,这是否意味着内存已经启动了一个名为p+1的新指针

内存是“分配”的,不一定来自RAM,但它没有给出名称-它是一个未命名的临时值。它可能只存在于CPU寄存器中

2如果上面的答案是否定的,那么内存没有为p+1分配内存,当我们使用*p+1时,我们仍然可以得到值11,这是否意味着只要我们知道地址,这个符号*就可以在没有指针的情况下使用

将创建一个临时指针,用于*p+1解引用

内存将分配内存

编译器将生成留出内存的代码。当您声明int*p时会发生这种情况;然后在代码中的某个地方使用变量p。不管你如何使用它

这是否意味着只要我们知道地址,这个符号*就可以不用指针使用

这个问题毫无意义。如果没有指针操作数,您将如何使用*呢

不太清楚你想做什么。要获取存储在已知地址的内容,必须具有指针类型,并且必须使用*运算符

所以理论上你可以做一些愚蠢的事情,比如

*(int*)(0x12345678 + 1*sizeof(int)) 
或同等品

((int*)0x12345678)[1]
如果您知道数组存储在地址0x12345678。但实际上,您永远不会编写这样的代码,因为它很难看,地址可能会更改

内存将分配内存

编译器将生成留出内存的代码。当您声明int*p时会发生这种情况;然后在代码中的某个地方使用变量p。不管你如何使用它

这是否意味着只要我们知道地址,这个符号*就可以不用指针使用

这个问题毫无意义。如果没有指针操作数,您将如何使用*呢

不太清楚你想做什么。要获取存储在已知地址的内容,必须具有指针类型,并且必须使用*运算符

所以理论上你可以做一些愚蠢的事情,比如

*(int*)(0x12345678 + 1*sizeof(int)) 
或同等品

((int*)0x12345678)[1]
如果您知道数组存储在地址0x12345678。但实际上,您永远不会编写这样的代码,因为它很难看,而且地址是m
可以更改。

让我们假设存在声明

int a[] = {10, 11};
int *p = a;
在这种情况下,变量p由数组a的第一个元素的地址初始化

要计算此表达式

p + 1
p++;
编译器获取存储在指针p中的值,并根据指针算法将表达式sizeof int的值添加到该值中。因此,表达式生成一个新地址,该地址指向数组a的第一个元素之后的内存,该元素是数组a的第二个元素的地址,计算值是数组a的第二个元素的地址

事实上,编译器可以创建int*类型的临时对象来存储这个中间值。但对象的生存期不超过表达式本身的生存期

可以将运算符*应用于具有指针类型的表达式

考虑一下这个代码

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+1

假设存在声明

int a[] = {10, 11};
int *p = a;
在这种情况下,变量p由数组a的第一个元素的地址初始化

要计算此表达式

p + 1
p++;
编译器获取存储在指针p中的值,并根据指针算法将表达式sizeof int的值添加到该值中。因此,表达式生成一个新地址,该地址指向数组a的第一个元素之后的内存,该元素是数组a的第二个元素的地址,计算值是数组a的第二个元素的地址

事实上,编译器可以创建int*类型的临时对象来存储这个中间值。但对象的生存期不超过表达式本身的生存期

可以将运算符*应用于具有指针类型的表达式

考虑一下这个代码

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+1

你说的是记忆在做事情,这并不是记忆的工作原理。理解你的意思有点困难。你能不能也稍微修改一下你的代码格式?1。否。内存已分配给a。p指向a的开头,p+1指向a[1]。2. * 当应用于指针时,获取指针指向的对象,因此在本例中为[1]=11@unwind我编辑了这个问题来表达我认为用户的意思。瑞芝:如果我假设错了,请再纠正我。当我们说int x=5时;编译器将为保存数字5的整数x分配内存。但是如果我们说x+1,这是否意味着一些内存已经用一个新的整数x+1初始化了呢?你说的是内存在做事情,这并不是内存的工作原理。理解你的意思有点困难。你能不能也稍微修改一下你的代码格式?1。否。内存已分配给a。p指向a的开头,p+1指向a[1]。2. * 当应用于指针时,获取指针指向的对象,因此在本例中为[1]=11@unwind我编辑了这个问题来表达我认为用户的意思。瑞芝:如果我假设错了,请再纠正我。当我们说int x=5时;编译器将为保存数字5的整数x分配内存。但是如果我们说x+1,这是否意味着一些内存已经用一个名为x+1的新整数初始化?谢谢你的回答,这是否意味着:如果我有一个地址,这个地址将转换为指针类型或地址是指针类型?因为您说过*可以应用于指针类型的表达式。。。。有点困惑,试着更深刻地理解。非常感谢你,这对我很有帮助lot@Ruizhi指针和地址这两个词通常可以互换使用。@Ruizhi-an-address实际上只是机器指令级使用的一个数字。在典型的C实现中,指针值只是它指向的对象的地址,但这只是一个实现细节。谢谢你的回答,这是否意味着:如果我有地址,这个地址将转换为指针类型或地址是指针类型?因为您说过*可以应用于指针类型的表达式。。。。有点困惑,试着更深刻地理解。非常感谢你,这对我很有帮助lot@Ruizhi指针和地址这两个词通常可以互换使用。@Ruizhi-an-address实际上只是机器指令级使用的一个数字。在典型的C实现中,指针值只是它指向的对象的地址,但这只是一个实现细节;它实际上在低级驱动程序、CPU设置等程序中是不可或缺的。@PeterA.Schneider不,不是真的。这样的程序会有注册映射头,在那里你会得到一些作为变量或指针的东西。例如,映射可以包含这样一个寄存器定义:define PORTX*volatile uint32\u t*0x12345678。这并不意味着appl
应用程序应该运行并在代码中间执行这些转换。这样做是愚蠢的,会使程序无法阅读。相反,应用程序应该像使用任何普通32位变量一样使用PORTX;我刚才说过,我们似乎同意这一点,将整数文本转换为指针有合法的甚至必要的用例。没有经验的读者在阅读你的愚蠢和理论的时候可能会错过这一点;它实际上在低级驱动程序、CPU设置等程序中是不可或缺的。@PeterA.Schneider不,不是真的。这样的程序会有注册映射头,在那里你会得到一些作为变量或指针的东西。例如,映射可以包含这样一个寄存器定义:define PORTX*volatile uint32\u t*0x12345678。这并不意味着应用程序应该运行并在代码中间执行这些转换。这样做是愚蠢的,会使程序无法阅读。相反,应用程序应该像使用任何普通32位变量一样使用PORTX;我刚才说过,我们似乎同意这一点,将整数文本转换为指针有合法的甚至必要的用例。没有经验的读者在阅读你的愚蠢的理论文章时可能会错过这一点。我想知道我们是否还应该提到*是一个可以为类重载的运算符。@AndyG这个运算符已经重载了,因为它可以用作乘法运算符。我想知道我们是否也应该提到*是一个可以重载的运算符对于类。@AndyG此运算符已重载,因为它可以用作乘法运算符: