c语言 - A[m][n] 中的 A 不是指针吗(当我们使用指针定义二维矩阵时进行类比)



A[0]A[1]显然是指数,毫无疑问,要指向各个数组。但是A不应该是指向A[0]的指针,因为在GCC中编译printf("%d", A)会导致以下错误:

格式%d期望类型int的参数,但参数2具有类型int *

如果A不是指针,那么为什么使用指针定义2D矩阵时会考虑指针。

此外,printf("%d", *(A+1)[0]);的工作非常好,暗示A被渲染为指针。如果是这种情况,printf("%d", A)应该打印A[0]的地址,但显示汇编错误。

这个问题归结为是否是指针,而不是不是。查看此问题:数组是指针吗?

当您使用

int arr = {1, 2, 3, 4};
int *p = arr;

ARR从INT数组转换为指针转换为INT。它和做的一样。

int *p = &arr[0]

也发生了同样的事情
printf("%d", A)

这就是为什么编译器会给您信息的原因,但这可能会令人困惑,并可能导致人们认为指针和数组确实是相同的。

有许多不同的方法来创建int的所谓 2D矩阵,每个矩阵定义了非常不同的对象类型:

  1. 作为int的数组数组:

    int A[ROWS][COLS] = { 0 };
    
  2. 作为int数组的一系列指针:

    int *A[ROWS];
    for (int i = 0; i < ROWS; i++)
        A[i] = calloc(sizeof(int), COLS);
    
  3. 作为int数组数组的指针:

    int (*A)[COLS] = calloc(sizeof(*A), ROWS);
    
  4. 作为指向int阵列的一系列指针的指针:

    int **A = calloc(sizeof(*A), ROWS);
    for (int i = 0; i < ROWS; i++)
        A[i] = calloc(sizeof(int), COLS);
    

在所有情况下,访问矩阵元素的语法都是相同的: A[row][col]或任何等效指针符号变体:

    *(*(A + row) + col)
    *(A[row] + col)
    (*(A + row))[col]

在所有情况下,AA[row]都可以在预期指针的情况在表达式上下文中使用(作为sizeof的参数除外(,例如将作为参数传递给printf

printf打印指针值需要%p转换格式。

%d期望的int与指针不同,可能具有不同的尺寸,并且可能以不同的方式传递给printf,所有这些都会导致不确定的行为。编译器对此发出非常有用的警告。最好用尽可能多的警告配置编译器来发现愚蠢的错误。这些警告有时很难理解,但几乎总是表明需要修复的事情。

您可以使用printf("%p", (void*)A)等效于printf("%p", (void*)&A[0])printf("%p", (void*)A[0]),等效于printf("%p", (void*)&A[0][0])。所有4个都应打印相同的地址。

最新更新