2009-11-04 235 views
2
char* p = "hello world"; 

程序员通常将一个变量的地址赋给一个指针。但在上述情况下,指针指向哪里?这个指针做了什么?

,并在世界上是什么

int x =42; 
int* p= &x; 
int ** r = &p; 
+1

不,*符号通常不会将变量的地址分配给指针。它总是将一块内存的地址分配给一个“指针变量”。在某些情况下,地址是一段数据的地址,在其他情况下,它是包含变量值的一段内存的地址。如果您了解了一些关于在汇编程序中编程的知识,并且使用像DOS调试命令这样的基本调试程序来调试机器代码的执行,那么理解C的这一方面会更容易。 – 2009-11-04 07:25:37

+7

这是怎么回事,在这里连续发表你的作业题目? – DVK 2009-11-04 07:26:40

+0

“克里斯,我误解了我的问题**” - 你甚至读过答案吗?变量的名称和类型不会改变发生了什么的想法。 – Groo 2009-11-04 07:36:18

回答

14

它指向包含ASCII序列hello world的程序只读存储器中的区域(通常在程序的机器码本身中)。与此相比,:

char p[] = "hello world"; 

其产生的12个char S中的堆栈上的阵列,这是可以修改的,就像任何其他变量,以及:

char *p = strdup("hello world"); 

其产生的12 char秒的阵列在堆上,并且将p设置为指向这个可读的堆可写入的空间的存储器。

至于你(完全无关)的第二个问题:

int** r = &p; 

简单比它的外观,虽然这也是不好的。 &p地址的p。所以,如果我们这样做:

int x; 
int *y = &x; 

然后将鼠标指针y变量x,所以分配给*y改变x(反之亦然)。我们可以对任意复杂类型做到这一点:

int *x; 
int **y = &x; 

现在y仍指向x一个指针,但x也是一个指针。因此,在您的示例中,r是指向指向int的指针,它的值是p(指向char的指针)的地址。但是,这样做不好,因为许多平台在从char *类型转换为较大的指针类型时都存在对齐问题。

+0

我记得读过关于字符串文字的东西会自动转换为一个临时的全局变量。这是你在第一个例子中提到的吗?谢谢 – user133466 2009-11-04 07:17:37

+0

字符串文字只是程序中的一系列只读数据,就像数字常量和其他类似的东西一样。 'char * p =“string”'只是将指针'p'指向那部分数据。 – 2009-11-04 07:21:23

+0

为什么要创建一个指针指向“坏”的指针?它是改变函数输入指向堆的唯一方法。 – 2009-11-04 08:45:57

3

的字符串常量“Hello World”的必须驻留在某个应用程序,并在运行时加载到内存中。通常这是在可执行文件的数据部分。指针p指向内存中的这个地址。

第二个例子简单地取p的地址。鉴于p在堆栈上,它将成为当前堆栈的地址。

0

p指向以NUL结尾的字符串的第一个字符。 r指向一个指针......也就是说它指向一个指向一个整数的持有指针的位置。

1

当声明一个指针时使用的星号表示它只是一个指针(它是它的类型化合指定符的一部分),并且不应该与取消引用操作符(也是星号)混淆。

如果要访问它返回的值,则必须在它之前加上一个双星号。

-1

p是存储有"hello world"的存储器地址,所以存储器p'address具有地址位置...

int** r = &p;

所以r是到该地址的参考...有点儿弄乱

2

插图可能会有所帮助。鉴于以下声明:

char *s = "hello world"; 
int x = 45; 
int *p = &x; 
int **r = &p; 
char q[] = "hello world"; 

承担下列存储器映射(地址和布局完全是任意的,并不意味着代表任何真实世界的架构):

 
       0x00 0x01 0x02 0x03 
    0x00008000: 'h' 'e' 'l' 'l' 
    0x00008004: 'o' ' ' 'w' 'o' 
    0x00008008: 'r' 'l' 'd' 0x00 
    ... 
s: 0x01000000: 0x00 0x00 0x80 0x00 
x: 0x01000004: 0x00 0x00 0x00 0x2D 
p: 0x01000008: 0x01 0x00 0x00 0x04 
r: 0x0100000C: 0x01 0x00 0x00 0x08 
q: 0x01000010: 'h' 'e' 'l' 'l' 
    0x01000014: 'o' ' ' 'w' 'o' 
    0x01000018: 'r' 'l' 'd' 0x00 

字符串“你好世界“是包含静态范围的charconst char,在C++中)的12个元素的数组,这意味着在程序启动时分配内存并保持分配状态直到程序终止。确切地说,字符串文字在内存中的位置取决于平台,但最好假设内存是不可写的(即,不能用strcpy()strcat()sprintf()等来更改它的内容)。该语言标准明确指出试图修改字符串文字会导致未定义的行为。

线

char *s = "hello world"; 

限定s作为指针以炭与文字的地址(0x00008000在本例中)进行初始化。

线

int x = 45; 

x定义为一个整数,并与值45(16进制数2D)进行初始化。

线

int *p = &x; 

p定义为一个指针int和与x(0x01000004)中的地址进行初始化。

线

int **r = &p; 

r定义为一个指针的指针为int并用的p(0x01000008)中的地址进行初始化。

请注意,指针类型是不同的,并不总是兼容的。尽管sp,并且r都决心的32位地址值在这个特定的假设,他们有不同的类型不一定互换,即使他们都设置为指向同一位置。一些平台针对不同的指针类型使用不同的大小和表示。

最后,作为一个额外的好处,我们有线

char q[] = "hello world"; 

其中q定义为炭的12个元素的数组(从字符串文字的大小取尺寸被用来初始化)并使用字符串文字的内容对其进行初始化。