【问题标题】:Assigning a pointer to a array of pointers to char将指针分配给指向 char 的指针数组
【发布时间】:2011-04-02 02:19:59
【问题描述】:

gcc 4.4.4 c89

#define SIZE 5
    char *names[SIZE] = {"peter", "lisa", "simon", "sarah", "julie"};
    char *search_names[SIZE] = {0};
    size_t i = 0;

    for(i = 0; i < SIZE; i++ ) {
        search_names[i] = names[i]++;
    }

    for(i = 0; i < SIZE; i++) {
        printf("name to search for [ %s ]\n", search_names[i]);
    }

我对 search_names[i] = names[i]++; 这一行感到困惑,这是一个指向 char* 的指针数组。只是我的实验我在想它应该是&amp;names[i]++。因为我想在那个位置获得指针。所以拥有 & 会让我得到指针指向的地址。

我想我也可以像这样递增:(names[i]) + i;

只是对那条线感到困惑。

【问题讨论】:

  • 我不认为我完全理解您的代码的意图。这两个数组都是指向 char 的指针数组。您只是将一个数组复制到另一个数组吗?在这种情况下,它应该只是“search_names[i] = names[i];”。为什么你需要增加呢?
  • 是的,你是对的。我只是在试验和尝试不同的东西。但是,search_names[i] = names[i];产生与 search_names[i] = names[i]++; 相同的结果这是否意味着它们在某种意义上是平等的。 names[i]++ 会增加什么?谢谢。
  • names[i] 指的是一些字符串,例如“peter”。在 C 中,字符串存储为字符数组,以“\0”结尾。当你抓取 names[i] 时,你实际上是在抓取一个指向位于 names[i] 的字符串中第一个元素的指针,换句话说,是一个指向 "peter\0" 中的 "p" 的指针。当您增加该指针时,它会向前移动一个空格,指向“e”,形成“eter\0”。但是,由于模糊的优先规则,在分配给 search_names[i] 之后会发生增量,所以看起来相同,但是您正在执行额外的指针操作。

标签: c pointers


【解决方案1】:

names[i] 是一个指针,类型为char*&amp;names[i] 是指向names[i] 的指针,因此具有char** 类型。一些记忆的图片:

names                    for each i, this is where names[i] *points*
|__________________          0     1    2     3     4
|                  |         |     |    |     |     |
|                  |         v     v    v     v     v
[0 ][1 ][2 ][3 ][4 ]  <gap>  peter0lisa0simon0sarah0julie0
        ^
        |_This is where &names[2] points, i.e. this is where names[2] *is*

name 是一个由 5 个指针组成的数组,我用方括号和它的索引来描述每个指针。加上一个空格,因为指针在我的机器上是 4 字节。这是刚刚初始化names 之后的情况。右侧单独的内存块是一个字节序列,每个0 表示一个0 / NUL 字节,而不是字符0。为字符串文字分配内存是实现(编译器、链接器和加载器一起工作)的责任 - 我假设您使用的所有字符串文字都将聚集在一起,尽管情况并非如此。最后,数字 0 ... 4 表示names 中的每个指针指向的位置。

由于您要分配给char*,因此您需要char*。或者以另一种方式看待它,当(且仅当)指针本身具有相同的值时,指针指向同一事物。所以如果你想让search_names[i](它是一个指针)指向names[i]指向的同一个东西,那么search_names[i] = names[i]是完全正确的。

不过,我不知道names[i]++ 的意图是什么。它修改了指针names[i]。修改指针使其指向不同的事物。在这种情况下,您最终会得到 names[0] 指向“eter”,names[1] 指向“isa”,等等。

这是在 names 中增加每个指针后内存的样子:

names                
|_____________           0     1    2     3     4
|             |          |     |    |     |     |
v             v          v     v    v     v     v
[0][1][2][3][4]         peter0lisa0simon0sarah0julie0

顺便说一句,您允许将字符串文字分配给char*,但这并不意味着您应该。最好声明您的数组const char *names[SIZE]。修改编译器为字符串文字分配的内存是未定义的行为,使用const char* 而不是char* 有助于强制执行此操作。

【讨论】:

    【解决方案2】:

    names[] 被定义为指向字符的指针数组。因此,names[i] 是指向名称中包含的第 i 个字符串的指针。 search_names[] 也是一个指向 char 的指针数组,因此 search_names[i] 也是一个指针。因此,无需将地址运算符应用于 names[i] 以使 search_names[i] 指向与 names[i] 相同的字符串。希望这可以为您澄清事情。

    【讨论】:

      【解决方案3】:

      所以你试图将数组名称复制到 search_names 中?请注意,names 和 search_names 都是指向字符的指针。 IE,names[i] 是一个指针。

      表达式

      search_names[i] = names[i]
      

      将 search_names[i] 的值指定为 names[i]。这只是将运行时堆栈中地址 &names[i] 的内容放入地址 &search_names[i] 的单元格中。在这种情况下,它只是复制一个指针。它不会复制字符。它只会复制单元格名称[i]中的内容——指向字符序列第一个字符的指针。

      原因

      search_names[i] = names[i]++; 
      

      等价于

      search_names[i] = names[i]
      

      在 search_names 的上下文中是因为自增运算符会影响 names[i] 的值。它在赋值运算符之后具有较低的优先级。所以表达式将在赋值后增加 names[i]。由于 names[i] 是一个指针,因此增量会进行一些指针运算,这意味着它将指向地址 (names[i] + sizeof(char) )。

      【讨论】:

        猜你喜欢
        • 2018-10-06
        • 2018-05-16
        • 2018-04-05
        • 1970-01-01
        • 2016-04-19
        • 2014-08-23
        • 2015-10-26
        • 2021-01-26
        • 2011-05-23
        相关资源
        最近更新 更多