A [m] [n]中的A不是指针(从我们使用指针定义2维矩阵时的类比)[复制]

问题描述 投票:-2回答:2

这个问题在这里已有答案:

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]的地址,但它显示编译错误。

c arrays pointers
2个回答
1
投票

这个问题归结为数组是否是指针,而事实并非如此。看到这个问题:Arrays are Pointers?

当你使用

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

arr从int数组转换为指向int的指针。它和做的一样。

int *p = &arr[0]

同样的事情正在发生

printf("%d", A)

这就是编译器为您提供消息的原因,但这可能令人困惑,并且可能导致人们认为指针和数组确实相同。


1
投票

有许多不同的方法可以创建所谓的int二维矩阵,每个矩阵定义一种非常不同类型的对象:

  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]都可以在指向预期的地方使用,因为它们确实是指针(情况3和4),或者因为数组(情况1和2)在使用时会衰减到指向其第一个元素的指针表达式上下文(除了作为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应该打印相同的地址。

© www.soinside.com 2019 - 2024. All rights reserved.