如果这是一个重复的问题,请原谅
这是我的代码
#include "stdafx.h"
#include <stdio.h>
#include "iostream"
#include <stdlib.h>
using namespace std;
int main()
{
char * name = "Hello";
cout << "2" << endl;
cout << "Address2 is " << &name << " value at address is " << * (&name) << endl;
cout << "Next address2 is " << &name + 1 << " value at address is " << name + 1 << " " << sizeof(char) << endl;
cout << "3" << endl;
cout << "Address3 is " << &name << " value at address is " << name << endl;
cout << "Next address3 is " << &name + sizeof name << " value at address is " << name + sizeof name << endl;
getchar();
}
这是输出
Address2是003EFAA4,地址为Hello //我很容易理解
下一个地址2是 003EFAA8(这是我很难理解的地方。我的理解是,考虑到char为1字节,下一个地址应该是003EFAA5吗?
输出与1相同
下一个地址2是 003EFAB4(这也是我很难理解的地方。我的理解是,考虑到char指针的大小为4字节,当变量名的地址为003EFAA4时,下一个地址应为003EFAA8? / strong>
我对内存的理解是地址是以字节为单位引用的。如果是这样,那么为什么在上面的数字3中给我的地址再增加4个字节,而在上面的数字4中给我的下一个地址又再增加10个字节?
任何解释将不胜感激。谢谢
答案 0 :(得分:10)
下一个地址2是003EFAA8(这是我很难理解的地方。我的理解是,考虑到char为1字节,下一个地址应该是003EFAA5?
执行&name + 1
后,您将转到name
类型的下一个地址。 name
不是char
。它是一个char*
,在您的系统上,一个char*
的大小为4。这就是为什么它向前移4个字节的原因,因为这是下一个char*
所在的位置。>
下一个地址2是003EFAB4(这也是我也很难理解的地方。我的理解是,考虑到char指针的大小为4字节,当变量名的地址为003EFAA4时,下一个地址应该是003EFAA8。
这基本上与上面发生的事情相同,但是要转到下一个元素char*
,而不是转到下一个sizeof name
,在本例中,它是第四个元素。
答案 1 :(得分:8)
&name
的类型为char**
。指针算术的工作方式(如果添加)会增加char*
的大小几倍(因为char**
指向char*
,因此它将指向如果存在char*
数组,则下一个char*
。在您的系统上,char*
的大小看起来是4
。因此,如果&name
是003EFAA4
,那么&name + 1
是003EFAA8
(还有4
)。
sizeof name
是4
,因此,如果将其添加到&name
,它会增加16
。因此,乳清会使您得到003EFAB4
,比0x10
多16
(或003EFAA4
)。
答案 2 :(得分:6)
您这里的间接访问级别太多。
&name
是一个字符**,即指向字符指针的指针。这意味着,如果您+1,那么您将添加指针的大小,而不是字符的大小。 name
已经是一个字符*。
然后的问题是对名称进行指针算术运算,然后使用cout而不是新char *处的字符串打印指针地址。您可以通过强制转换为void *来实现此目的,例如
cout << "Next address2 is " << (void*)(name + 1)
使用C样式强制转换。
答案 3 :(得分:6)
欢迎使用指针算术。
char *name = "hello";
name
是指向字符的指针。它存储"hello"
字符串文字的地址,即。字符h
的地址(数组的地址等于(等于值)数组的第一个元素的地址)。您应该注意,字符串文字是不可变的,您无法对其进行修改。因此,最好将类型更改为const char*
。
&name
这是指向变量名的指针。不是指向"hello"
字符串文字的指针,而是指向指针的指针。 003EFAA4
是name
变量的地址。变量是由编译器在main()
函数内部的堆栈上分配的。
*(&name)
*&
规则(在此处)自行排除。因此*&name
等于name
。这将打印name
指针的值,即。这是指向"hello"
字符串文字的指针,即。这是指向h
字符串文字内的字符"hello"
的指针。不是&name
。 h
个字符的地址。
&name + 1
&name
具有char **
类型,即它作为指向字符的指针的指针。根据指针算法,&name + 1
等于(uintptr_t)&name + 1 * sizeof(*&name)
的值。 sizeof(*&name)
是sizeof(name)
,它是sizeof(char*)
,所以它是(uintptr_t)&name + sizeof(char*)
。在您的体系结构上,sizeof(char*)
是4字节(32位系统?),因此指针增加了4。即。 003EFAA4 + 4 = 003EFAA8
。
name + 1
name
的类型为char*
。根据指针算术,name + 1
等于(uintptr_t)name + sizeof(*name)
。 sizeof(*name)
是sizeof(char)
。 sizeof(char)
被定义为等于1。这将在e
字符串文字中打印"hello"
char的地址。
&name + sizeof name
&name
的类型为char**
,因此&name
的值递增sizeof(name) * sizeof(char*) times. As
sizeof(name)is equal to
sizeof(char *){{ 1}} sizeof(char *)* sizeof(char *), this is
4 * 4 = 16`。
ie.
这将指针name + sizeof name
的值增加name
的值。 sizoef(name) * sizeof(char)
是sizeof(name)
是sizeof(char*)
在您的体系结构上,4
是1。因此sizeof(char)
是{{1}中的字符name + sizeof name
的地址}字符串文字,即。 o
。
@edit重写了一些部分