二维数组程序的输出

时间:2013-06-01 05:04:31

标签: c arrays

以下程序的输出是什么?

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]。任何人都可以提供详细解释吗?

感谢您的帮助。

6 个答案:

答案 0 :(得分: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()程序更清晰。其他三个函数处理字符串的格式和要打印的值。代码有点错综复杂,但比这更清晰,而不是没有函数编写(我试过了;正在分析的内容的细节在必要的代码中完全丢失了。)

答案 1 :(得分:2)

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

编辑n*n在这方面为 2d数组提供相同的值

指数从C语言的0开始。因此,当您使用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

我希望你明白......

答案 2 :(得分:0)

答案是

row0的地址,垃圾值,1

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

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

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

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

这就是垃圾价值的原因。

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

This is sample array allocated dynamically

如果数组定义了静态,那就像

   0    1    2    3   4   5      6  7  8 
|              |             |             |
|[0][0]        |             |             |
|--row 0-------| row 1       |----row 1----|            

答案 3 :(得分:0)

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

如果您要在矩阵中打印2 X 23 X 3元素,则应打印arr[1][1]arr[2][2]

答案 4 :(得分:0)

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

答案 5 :(得分: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将打印数组的起始地址。