2012-04-11 347 views
2

有人能给我一个简短的解释,说明在下面的函数中发生了什么不同吗?指向指针的指针和指向数组的指针

void f1(data_t **d) 
    { 
     for (int i=0; i<MAXSIZE; i++) 
     { 
      (*d)[i].ival = i; 
     } 
    } 

    void f2(data_t **d) 
    { 
     for (int i=0; i<MAXSIZE; i++) 
     { 
      (*d)->ival = i; 
      (*d)++ 
     } 
    } 

    void f3(data_t *d) 
    { 
     for (int i = 0; i<MAXSIZE; i++) 
     { 
      d->ival = i; 
      d++; 
     } 
    } 

    void f4(data_t *d) 
    { 
     for (int i = 0; i<MAXSIZE; i++) 
     { 
      d[i].ival = i; 
     } 
    } 

特别是在f2中发生了什么不同。但每件事情都有明显的不同。

f1和f3做同样的事情(但不同)。 F2彻底失败了,和F4是越野车(工作在这个例子中,但是当我试图把其他值转换为其他指针(字符*)的字符串结束奇怪。)

+0

你如何解释你认为正在发生的事情...... – 2012-04-11 06:34:29

+3

这是功课吗? – loganfsmyth 2012-04-11 06:37:05

+1

是这种家庭吗? – giorashc 2012-04-11 06:37:50

回答

2
void f1(data_t **d) 
{ 
    for (int i=0; i<MAXSIZE; i++) 
    { 
     (*d)[i].ival = i; 
    } 
} 

的d似乎是一个指针到data_t的数组(或者是data_t数组的1个元素的数组)。解除引用来恢复data_t的数组,然后修改此数组的第i个元素。

void f2(data_t **d) 
{ 
    for (int i=0; i<MAXSIZE; i++) 
    { 
     (*d)->ival = i; 
     (*d)++ 
    } 
} 

这是有点棘手,确实做了一些不同于第一种情况。有一个指向data_t数组的指针。这里我们有一个指向data_t的指针数组。取消指向第一个元素的指针以检索指向数据的指针。然后 - >用于访问数据并修改值(x-> y =(* x).y)。最后,指针移动到主数组的下一个元素。

void f3(data_t *d) 
{ 
    for (int i = 0; i<MAXSIZE; i++) 
    { 
     d->ival = i; 
     d++; 
    } 
} 

下面我们就简单的情况下,d只是data_t一个数组的指针被访问。在循环内部,一个元素通过 - >来访问,然后d递增以指向数组的下一个元素。

void f4(data_t *d) 
{ 
    for (int i = 0; i<MAXSIZE; i++) 
    { 
     d[i].ival = i; 
    } 
} 

与f3类似,元素由[]运算符修改。

请注意以下事实:

int[] =(def) int * 

如果一个的类型是int *和i为任何整数类型,那么:

*(a + i) =(def) a[i] 

此外,如果一个点的一个第一元件阵列,然后

*a =(def) a[0] 

,然后,一 “一++” 之后

*a =(def) a[1] 

...等等。

+0

这对我的理解是一个巨大的帮助!!!上面的代码中做了什么(def)? – Sun 2012-04-11 07:15:58

+0

=(def)等于“意味着同样的定义“,它不是一个真正的源代码 – Spook 2012-04-11 07:21:58

1

让我们这些一次一个:

// f1 
(*d)[i].ival = i; 

首先,(*d)被解除引用d,这似乎是一个指针,指向data_t变量的阵列。这允许访问实际的数组,因此[i]正在访问数组的i个元素并将i赋值给它。

// f2 
(*d)->ival = i; 
(*d)++; 

(*d)被提领d就像在第一个。但是,在继续之前,有一点关于阵列的信息是您应该了解的。

int j[2] = { 42, 50 }; 
int j0 = *j; // j0 is now 42 
j += 1; 
int j1 = *j; // j1 is now 50 

阵列被实现为在存储器“插槽”顺序地面向各个变量,和阵列实际上只是一个指向第一个时隙。因此,*j是提领j,它目前指向第一个元素,导致42。做j += 1提前指针一个“插槽”,这样*j现在将导致50

现在回到f2(*d)->ival(**d).ival完全相同。这很像我上面给出的简单例子。下一行(*d)++正在将指针前进到下一个“插槽”。考虑在内存中什么是“新锐”这个简单的示意图:

 +------+------+ 
     |*(j+0)|*(j+1)| 
j --->|------|------| 
     | 42 | 50 | 
     +------+------+ 

j指向第一个“插槽”,在第一行中所示的间接引用,在第二个值。

f3非常像f2,除了它期望数组作为参数传递,而不是指向它的指针。因此,d只需要与->运营商一起解除引用(再次,完全像(*d).ival)。

f4非常像f1,只是它期望数组作为参数传递,而不是指向它的指针。因此,d[i]正在直接访问数组的第i个元素i

+0

这也是一个巨大的帮助!谢谢! – Sun 2012-04-11 07:19:34

1
void f1(data_t **d) 
    { 
     for (int i=0; i<MAXSIZE; i++) 
     { 
      (*d)[i].ival = i; 
     } 
    } 
  1. 你得到一个指针阵列**ddata_t,其中元件是一个结构,具有字段ival
  2. 访问阵列*d
  3. 迭代所有数组元素,元件通过元件,改变索引i。并且更新ival的每个数组元素为i

注意:不要t change the pointer * D',指向数组开始

void f2(data_t **d) 
{ 
    for (int i=0; i<MAXSIZE; i++) 
    { 
     (*d)->ival = i; 
     (*d)++ 
    } 
} 
  1. 你得到一个指向data_t阵列**d,且该元素的结构,具有场ival
  2. 访问阵列*d ,这也是一个指针阵列(第一元件)
  3. 更新由所述(上文)元件的ivali,使用指针符号(*d)->ival = i;
  4. 提升指向下一个数组元素的指针(*d)++并返回2.从现在起* d是 指向“筛选”数组的开始。

    空隙F3(data_t * d)

    { 
        for (int i = 0; i<MAXSIZE; i++) 
        { 
         d->ival = i; 
         d++; 
        } 
    } 
    

    1。你得到data_t的数组*d,该元素是一个结构,具有字段ival

    2.也可以认为你得到一个指向数组的第一个元素的指针。 访问的访问和更新ivali,由指针:d->ival = i;

    3.Promote指针到下一个数组元素d++

    空隙F4(data_t * d)

    { 
        for (int i = 0; i<MAXSIZE; i++) 
        { 
         d[i].ival = i; 
         d++; 
        } 
    } 
    

f3。但您使用参考符号(按值)推荐索引并更新ival

+0

这是非常有用的信息,非常明确的解释。 – Sun 2012-04-11 07:32:39