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 有问题(在本例中有效,但是当我尝试将其他值放入其他指针(char *)时,字符串最终变得奇怪。)

4

3 回答 3

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 *

如果 a 是 int * 类型并且 i 是任何整数类型,则:

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

此外,如果 a 指向数组的第一个元素,则

*a =(def) a[0]

然后,在“a++”之后

*a =(def) a[1]

...等等。

于 2012-04-11T07:06:35.823 回答
1

让我们一次拿这些:

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

首先(*d)是解引用,它似乎是一个指向变量d数组的指针。data_t这允许访问实际数组,例如[i]访问数组的i第 -th 元素并分配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. Doingj += 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 个元素。

于 2012-04-11T07:08:05.017 回答
1
 void f1(data_t **d) 
    { 
        for (int i=0; i<MAXSIZE; i++) 
        { 
            (*d)[i].ival = i; 
        } 
    } 
  1. 你得到一个指向数组**d的指针data_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. 你得到一个指向数组**d的指针data_t,哪个元素是一个结构,有一个字段ival
  2. 访问数组*d,它也是指向数组的指针(第一个元素)
  3. 通过 to be更新ival(上面的)元素i,使用指针表示法(*d)->ival = i;
  4. 提升指向下一个数组元素的指针(*d)++并返回2.从现在开始 *d 指向“已筛选”数组的开头。

    无效 f3(data_t *d)

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

    1.你得到一个数组*ddata_t哪个元素是sa结构,有一个字段ival

    2.也可以认为你得到了一个指向数组第一个元素的指针。通过指针访问访问和更新ivalid->ival = i;

    3.提升指向下一个数组元素的指针d++

    无效 f4(data_t *d)

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

如 .但是您使用参考符号(按值)f3提升索引和更新ival

于 2012-04-11T07:25:33.507 回答