为C语言重新初始化指针

为C语言重新初始化指针,c,arrays,pointers,C,Arrays,Pointers,我目前正在通过丹·古金的书《傻瓜C编程入门》学习C编程 我目前阅读的一个主题是数组实际上是事实指针。Dan试图用以下代码证明: #include <stdio.h> int main() { int numbers[10]; int x; int *pn; pn = numbers; /* initialize pointer */ /* Fill array */ for(x=0;x<10;x++) {

我目前正在通过丹·古金的书《傻瓜C编程入门》学习C编程

我目前阅读的一个主题是数组实际上是事实指针。Dan试图用以下代码证明:

#include <stdio.h>

int main()
{
    int numbers[10];
    int x;
    int *pn;

    pn = numbers;       /* initialize pointer */

/* Fill array */
    for(x=0;x<10;x++)
    {
        *pn=x+1;
        pn++;
    }

    pn = numbers;

/* Display array */
    for(x=0;x<10;x++)
    {
        printf("numbers[%d] = %d, address %p\n",
                x+1,*pn,pn);
        pn++;
    }

    return(0);
}
#包括
int main()
{
整数[10];
int x;
int*pn;
pn=数字;/*初始化指针*/
/*填充数组*/

对于(x=0;x在填充数组期间,指针
pn
递增,数据放置在数组上。用于打印数组内容的指针变量相同。由于此重新初始化已完成。

由于
pn
在第一个循环中递增,在第一个循环完成后,
pn
将指向
之外的地址>数字
array。因此,您必须在第二个循环之前将
pn
初始化到数组的开头,因为您使用相同的指针打印内容。

,因为您已更改了以下代码段中语句
pn++
中包含的
pn
中的地址

for(x=0;x<10;x++)
    {
        *pn=x+1;
        pn++;
    }

for(x=0;x数组不是指针,但C允许您将数组分配给数组变量类型的指针,其效果是该指针将指向数组中的第一项。这就是
pn=numbers
的作用

pn
是指向int的指针,而不是指向数组。它指向单个整数。当您增加指针时,它只会移动到下一个内存位置。它所做的移动是指针类型的大小,因此在本例中为
int

那么这证明了什么呢?不是数组是指针,而是数组是一个连续的内存块,由数组项类型的N倍大小组成

当运行第二个循环时,指针到达一个不再属于数组的内存块,因此会得到“垃圾”,这只是碰巧存在于该位置的信息


如果要通过递增指针再次迭代数组,则必须重新初始化指向第一项的指针。for循环只做一件事,即计数到10。它不知道数组,也不知道指针,因此循环不会自动为您重置指针。

pn
指针用于指向
numbers
数组

第一个
for
-循环使用
pn
设置值,逐元素逐步通过数据元素。循环结束后,
pn
指向
数字的末尾(在未分配的第11个元素)


对于第二个
For
-循环,即使用
pn
通过单步遍历数组再次遍历
numbers
pn
需要移动到
numbers
数组的前面,否则您将访问不应该查看的内存(未分配内存)

一些细微的差别

int a[5];      /* array */
int *pa = a;   /* pointer */

pa[0] = 5;
printf("%d\n", a[0]);   /* ok it is the same here */
printf("address of array %p - address of pointer %p, value of pointer\n",
    &a, &pa, pa); /* &a is the same as pa not &pa */
printf("size of array %d - size of pointer %d\n", sizeof(a), sizeof(pa));
sizeof(a)
在这里
5*sizeof(int)
sizeof(pa)
是指针的大小

现在回答你的问题:


在第一个循环之后,
pn
指向
p[10]
,而不再指向
p[0]
。这就是为什么必须将其重置的原因。

仅为了将点返回,数组不是指针。当您将
数字声明为
整数[10]
时,内存中会出现以下内容:

         +---+
numbers: |   | numbers[0] 
         +---+
         |   | numbers[1]
         +---+
          ...
         +---+
         |   | numbers[9]
         +---+
没有为指向
数字
的第一个元素的单独指针留出存储空间。发生的情况是,当表达式
数字
出现在任何地方,并且它不是
大小的
或一元
&
运算符的操作数时,它会被转换(“衰减”)为“指向
int
的指针”类型的表达式,表达式的值是数组第一个元素的地址

您使用
pn
所做的是将其设置为指向
数字的第一个元素,然后在数组中“漫游”:

         +---+ 
numbers: |   | <------+ 
         +---+        |
         |   |        |
         +---+        |
          ...         |
         +---+        |
         |   |        |
         +---+        |
          ...         |
                      |
         +---+        |
     pn: |   | -------+ 
         +---+
         +---+ 
numbers: |   | 
         +---+ 
         |   | <------+
         +---+        |
          ...         |
         +---+        |
         |   |        |
         +---+        |
          ...         |
                      |
         +---+        |
     pn: |   | -------+ 
         +---+
每个
pn++
将指针向前移动,直到在第一个循环结束时,您有以下内容:

         +---+ 
numbers: |   | 
         +---+ 
         |   | 
         +---+ 
          ...  
         +---+ 
         |   | 
         +---+ 
          ...  <------+
                      |
         +---+        |
     pn: |   | -------+ 
         +---+
+--+
编号:||
+---+ 
|   | 
+---+ 
...  
+---+ 
|   | 
+---+ 

…“数组实际上是指针”不,他们不是。扔掉那本书……又是宾基的时候了:@truthsurum:别胡说了!听起来丹也可以用一本入门书。啊,我明白了。只是想澄清一点,这就是他想说的——代码真的是要证明数组是一个连续的内存块,其大小是typ的N倍不是为了证明数组是指针,而是为了证明数组是指针。只是这一章一般都是关于数组如何像指针一样工作的。很抱歉造成了混淆:(标准中没有垃圾。这是未定义的行为,没有其他东西。感谢您对指针和数组之间的区别给予启发(:感谢您的详细解释和直观演示。这对理解代码的工作原理非常有帮助。