0

以下程序的输出是什么?

main( ) 
{ 
 int n[3][3] = { 
 2, 4, 3, 
 6, 8, 5, 
 3, 5, 1 
 } ; 
 printf ( "\n%d %d %d", *n, n[3][3], n[2][2] ) ; 
} 

我以为它会打印出来-

address of first element, then 1 and then 8

但不知何故,它打印出前两个的垃圾值,然后是1 for n[2][2]. 任何人都可以对此提供详细解释吗?

谢谢您的帮助。

4

6 回答 6

3

学习和学习。

#include <stdio.h>
#include <inttypes.h>

static void print_address0(const char *tag, const void *addr, const void *addr_1);
static void print_address1(const char *fmt, int i, const void *addr, const void *addr_1);
static void print_address2(const char *fmt, int i, int j, const void *addr, const void *addr_1);

#define ANALYZE_0(val)            print_address0(#val, val, (val)+1)
#define ANALYZE_1(fmt, i, val)    print_address1(fmt, i, val, (val)+1)
#define ANALYZE_2(fmt, i, j, val) print_address2(fmt, i, j, val, (val)+1)

int main(void)
{
    int n[3][3] =
    {
        { 2, 4, 3 },
        { 6, 8, 5 },
        { 3, 5, 1 },
    };

    ANALYZE_0(&n);
    ANALYZE_0( n);
    ANALYZE_0(*n);
    for (int i = 0; i < 3; i++)
    {
        ANALYZE_1("*(n+%d)", i, *(n+i));
        ANALYZE_1("n[%d]",   i, n[i]);
        ANALYZE_1("&n[%d]",  i, &n[i]);
        for (int j = 0; j < 3; j++)
            ANALYZE_2("&n[%d][%d]", i, j, &n[i][j]);
    }
    return 0;
}

static void print_address0(const char *tag, const void *addr, const void *addr_1)
{
    printf("%-8s = 0x%.8" PRIXPTR, tag, (uintptr_t)addr);
    char buffer[16];
    snprintf(buffer, sizeof(buffer), "(%s)+1", tag);
    printf("; %-12s = 0x%.8" PRIXPTR "\n", buffer, (uintptr_t)addr_1);
}

static void print_address1(const char *fmt, int i, const void *addr, const void *addr_1)
{
    char buffer[16];
    snprintf(buffer, sizeof(buffer), fmt, i);
    print_address0(buffer, addr, addr_1);
}

static void print_address2(const char *fmt, int i, int j, const void *addr, const void *addr_1)
{
    char buffer[16];
    snprintf(buffer, sizeof(buffer), fmt, i, j);
    print_address0(buffer, addr, addr_1);
}

Mac OS X 10.8.3(64 位编译)上 GCC 4.7.1 的输出:

&n       = 0x7FFF5F2D74C0; (&n)+1       = 0x7FFF5F2D74E4
n        = 0x7FFF5F2D74C0; (n)+1        = 0x7FFF5F2D74CC
*n       = 0x7FFF5F2D74C0; (*n)+1       = 0x7FFF5F2D74C4
*(n+0)   = 0x7FFF5F2D74C0; (*(n+0))+1   = 0x7FFF5F2D74C4
n[0]     = 0x7FFF5F2D74C0; (n[0])+1     = 0x7FFF5F2D74C4
&n[0]    = 0x7FFF5F2D74C0; (&n[0])+1    = 0x7FFF5F2D74CC
&n[0][0] = 0x7FFF5F2D74C0; (&n[0][0])+1 = 0x7FFF5F2D74C4
&n[0][1] = 0x7FFF5F2D74C4; (&n[0][1])+1 = 0x7FFF5F2D74C8
&n[0][2] = 0x7FFF5F2D74C8; (&n[0][2])+1 = 0x7FFF5F2D74CC
*(n+1)   = 0x7FFF5F2D74CC; (*(n+1))+1   = 0x7FFF5F2D74D0
n[1]     = 0x7FFF5F2D74CC; (n[1])+1     = 0x7FFF5F2D74D0
&n[1]    = 0x7FFF5F2D74CC; (&n[1])+1    = 0x7FFF5F2D74D8
&n[1][0] = 0x7FFF5F2D74CC; (&n[1][0])+1 = 0x7FFF5F2D74D0
&n[1][1] = 0x7FFF5F2D74D0; (&n[1][1])+1 = 0x7FFF5F2D74D4
&n[1][2] = 0x7FFF5F2D74D4; (&n[1][2])+1 = 0x7FFF5F2D74D8
*(n+2)   = 0x7FFF5F2D74D8; (*(n+2))+1   = 0x7FFF5F2D74DC
n[2]     = 0x7FFF5F2D74D8; (n[2])+1     = 0x7FFF5F2D74DC
&n[2]    = 0x7FFF5F2D74D8; (&n[2])+1    = 0x7FFF5F2D74E4
&n[2][0] = 0x7FFF5F2D74D8; (&n[2][0])+1 = 0x7FFF5F2D74DC
&n[2][1] = 0x7FFF5F2D74DC; (&n[2][1])+1 = 0x7FFF5F2D74E0
&n[2][2] = 0x7FFF5F2D74E0; (&n[2][2])+1 = 0x7FFF5F2D74E4

输出显示了与数组元素关联的地址的许多变化。每行显示一个表达式的地址,以及同一个表达式的地址加一(差异表示指向的对象的大小,因此)。

代码使用宏封装重复的代码,使main()程序更清晰。其他三个函数处理要打印的字符串和值的格式。代码有点复杂,但这样比没有函数编写更清晰(我试过了;正在分析的细节完全丢失在必要的代码中)。

于 2013-06-01T06:33:26.393 回答
2

如果您希望*n为一维数组提供错误的矩阵的第一个值。**n打印矩阵的第一个值。所以,*n给出第一个元素的地址。

编辑:所以n*n在这方面为二维数组提供相同的值

语言中的索引从 0 开始C。因此,当您使用n[2][2]它时,它会给出第 3 行和第 3 列的值1

当您使用时,n[3][3]您超出了为矩阵声明的限制。您正在尝试访问您尚未声明的第 4 行第 4 列,并且该错误未由C.

概括

*n=address of first element of the matrix
**n=value of first element of matrix=2
n[2][2]=value of 3*3 cell=1
n[3][3]=value of 4*4 cell=garbage in your case

我希望你明白....

于 2013-06-01T05:25:20.457 回答
0

在 C 数组中,索引从 开始0,而不是在1。这就是为什么你会得到意想不到的结果。

如果要打印矩阵中的2 X 2and3 X 3元素,您应该打印arr[1][1]and arr[2][2]

于 2013-06-01T05:24:34.917 回答
0

数组首先索引来自 arr[0][0] 的星,并且在给定输入中 arr[3][3] 处没有值

于 2013-06-01T05:25:47.390 回答
0

C 中的数组从 0 索引开始。即在你的情况下:

  • n[0][0] = 2
  • n[0][1] = 4
  • n[0][2] = 3
  • n[1][0] = 6
  • n[1][1] = 8
  • n[1][2] = 5
  • n[2][0] = 3
  • n[2][1] = 5
  • n[2][2] = 1

n[2][2] 是数组的最大位置。这就是为什么当你尝试打印 n[3][3] 时,你会得到一些垃圾值。

*n 将打印数组的起始地址。

于 2013-06-01T05:29:21.053 回答
0

答案是

row0 的地址,垃圾值,1

*n 给出第一行的地址;所以 *n , n[0] 或 n+0, &n[0] 都给出了相同的答案。

arr[3][3] 超出范围,因为 c 中的索引从 0 开始。

int arr[]={0,1,2};

所以这里 arr[0]=0, arr 1 =1, and arr[2]=2

这就是为什么垃圾价值。

最后如上所述,arr[2][2] 返回 1。这是一个示例内存映射或动态分配的二维数组。

这是动态分配的示例数组

如果数组定义为静态的,它会喜欢

   0    1    2    3   4   5      6  7  8 
|              |             |             |
|[0][0]        |             |             |
|--row 0-------| row 1       |----row 1----|            
于 2013-06-01T05:14:54.213 回答