【问题标题】:Can I use pointer to print out arrays of int array just like arrays of string?我可以像字符串数组一样使用指针打印出 int 数组的数组吗?
【发布时间】:2015-04-07 06:09:45
【问题描述】:

如果我想打印出这样的字符串数组:

char juices_A[][12] = { "dragonfruit", "waterberry", "sharonfruit", };

我可以简单地使用juices_A[0],juices_A[1],juices_A[3],分别作为指向字符串"dragonfruit""waterberry""sharonfruit"的指针,然后打印出来。

但是如果我想打印出 int 数组的数组,比如:

int data[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

我不能简单地使用data[0],data[1],data[2]作为指向{ 1, 2, 3 },{ 4, 5, 6 },{ 7, 8, 9 }的指针,我需要采用更复杂的方式将它们打印出来。我需要在循环内使用循环。所以我想知道为什么我不能在 int 情况下使用指针?我在书上读到“数组变量就像指针..”所以我假设 int 数组变量 data[0],data[1],data[2] 也像指针......

#include <stdio.h>

int main() {

    int i_A = 0;
    char juices_A[][12] = { "dragonfruit", "waterberry", "sharonfruit", };
    for (; i_A < 3; i_A++)
        printf("%s;", juices_A[i_A]);
    puts("");

    int i_B = 0;
    int data[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
    for (; i_B < 3; i_B++) {
        int i_C = 0;
        for (; i_C < 3; i_C++)
            printf("%i,", data[i_B][i_C]);
        printf(";");
    }

    return 0;
}

结果是:

dragonfruit;waterberry;sharonfruit;
1,2,3,;4,5,6,;7,8,9,;

【问题讨论】:

  • 该语言将char* 视为一个字符串——一个具有终止空字符的字符数组。 intint* 没有类似的东西。 charchar* 在这方面很特别。
  • 你似乎理解得很清楚,参考上面的评论,简单的答案是'不'。
  • 顺便说一句,当您的数组被称为 juices_A 时,您的示例指的是 juice_A[0]

标签: c arrays pointers


【解决方案1】:

您可以使用指针等访问数组,反之亦然。

这是下面程序的输出:

dragonfruit;waterberry;sharonfruit;
{ { 1, 2, 3, }, { 4, 5, 6, }, { 7, 8, 9, }, }

这是对您的代码的修改:

#include <stdio.h>
#define ROW_WIDTH 3
#define TABLE_HEIGHT 3
int main(void) {

    char *juices[] = { "dragonfruit", "waterberry", "sharonfruit", };
    int data[TABLE_HEIGHT][ROW_WIDTH] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

    for (int n = 0; n < ROW_WIDTH; n++) 
        printf("%s;", juices[n]);

    int *ip = (int *)data;

    printf("\n{ ");
    for (int i = 0; i < TABLE_HEIGHT; i++) {
       printf("{ ");
       for(int j = 0; j < ROW_WIDTH; j++) {
           printf("%d, ", *ip + ((i * ROW_WIDTH) + j));
       }
       printf("}, ");
    }
    printf("}\n");
    return 0;
}

【讨论】:

  • 使用指针表示法的问题是你失去了 [] 表示法为你维护的边界感。所以在这个例子中,我们只是将数据视为我们有一个指针的单维整数数组,然后使用基本的矩阵数学将其表示为一个 H x W 表。 C 知道,因为它是一个指向需要移动的 int 数组的指针,所以对于每个“外部”增量 1,使用内部指针偏移 4 个字节。
  • @Allaboutthatbase2, in this example we just treat data like a single dimension array of ints that we have a pointer to ... 在实践中它有效,但它是未定义的行为,看看thisthis
  • 谢谢。第二个答案更容易理解,因为这是我的睡觉时间。我正在玩弄将数据转换为**,但由于时间已晚,我没有进一步追求。我不知道关于优化编译器的警告。如果有一个 C 编译器会在这种情况下中断,我真的会感到惊讶,因为很多人都依赖于可预测的数据布局。虽然有一个规范 - 我们都知道供应商和社区感到屈服于大众需求并容忍技术上不是他们最初打算的事情的压力:-) Keith 的回答非常好。
  • @AlterMann - 谢谢你让我诚实。我将不得不再次访问您引用的文字并尝试理解它。
  • @Allaboutthatbase2,不客气,I'd really be surprised if there's a C compiler that would break for cases like this,正如 Ken Thompson 在 cmets 中指出的那样,它足够安全,因为大多数 C 实现不进行数组边界检查,但正确的方法是通过指针处理该数组是使用int (*ip)[ROW_WIDTH] = data;
【解决方案2】:

字符串:

-------------------------
|h | e | l | l | o | \0 |
-------------------------
|w | o | r | l | d | \0 |
------------------------

如您所见,这个数组可以存储在二维字符数组中

char a[2][6];

现在a[i] 给出每行的起始地址,%s 打印出一个字符串,直到找到\0,这样您就可以传递每行的地址并获取该行的内容。就像

char *p = "hello";
printf("%s\n",p);

注意: 同样,如果您想在特定位置读取字符,则需要指定 a[row][col]

整数:

----------------
|1 | 2 | 3 | 4 |
----------------
|5 | 6 | 7 | 8 |
----------------

现在你可以有一个类似的数组

int b[2][4];

b[i] 将为您提供每行的起始地址,但为了获取存储在特定位置的值,您需要使用 b[row][col] 指定值。

不同之处在于有效 C 字符串的标记条件是 \0,它是用来访问每一行的,而整数不是这样的。

所以我假设 int 数组变量 data[0],data[1],data[2] 也像 指针

是的,它们是指向每一行的指针,但您需要取消引用指针才能获得正确的值?所以如果data[0] 是一个指针,那么就做data[0][column]

【讨论】:

    【解决方案3】:

    每当访问数据时,char juices_A[][12] = { "dragonfruit", "waterberry", "sharonfruit" }; 都会打印,直到达到 \0,因为字符串仅在 \0 之前被考虑。因此,当我们使用juices_A[0] 时,它指向第一个数据的开始,直到达到\0。但是要获得一个单独的字符,我们需要提及数组的两个维度。

    char juices_A[1][2]waterberry 中访问't'

    int 并非如此,因为每个都被视为单独的实体。所以我们使用数组的两个维度来访问它。

    即使我们在打印时像 char juices_A[][12] = { "dragon", "waterberry", "sharonfruit" }; 这样减小数组的大小,它也会输出

    dragon;waterberry;sharonfruit

    但在int data[3][3] = { { 1, 2}, { 4, 5, 6 }, { 7, 8, 9 } }; 的情况下,它会输出

    1,2,0,....` 这会有所不同

    【讨论】:

      【解决方案4】:
      #include <stdio.h>
      
      int main()
      {
          int data[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
          int *ptr;
          int lines = 3;
          int columns = 3;
          int i;
      
      
          ptr = &data[0][0];
      
          while (lines-- > 0) {
              i = columns;
      
              while (i-- > 0) {
                  printf("%d ", *ptr);
                  ptr += 1;
              }
      
              putchar('\n');
          }
          return 0;
      }
      

      或:

      #include <stdio.h>
      
      int main()
      {
          int data[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
          int *ptr;
          int lines = 3;
          int columns = 3;
          int max = lines * columns;
      
      
          ptr = &data[0][0];
      
          while (max-- > 0) {
              printf("%d ", *ptr);
              ptr++;
      
              if (max % columns == 0)
                  putchar('\n');
          }
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-09
        • 2021-12-05
        相关资源
        最近更新 更多