以下程序的输出是什么?
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]
。任何人都可以提供详细解释吗?
感谢您的帮助。
答案 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.这是动态分配的样本内存映射或二维数组。
如果数组定义了静态,那就像
0 1 2 3 4 5 6 7 8
| | | |
|[0][0] | | |
|--row 0-------| row 1 |----row 1----|
答案 3 :(得分:0)
在C数组中,索引从0
开始,而不是1
。这就是为什么你会得到意想不到的结果。
如果您要在矩阵中打印2 X 2
和3 X 3
元素,则应打印arr[1][1]
和arr[2][2]
。
答案 4 :(得分:0)
数组首先索引来自arr [0] [0]的星号,并且在给定输入中arr [3] [3]中没有值
答案 5 :(得分:0)
C中的数组以0索引开头。即在你的情况下:
n [2] [2]是数组的最大位置。这就是为什么当你尝试打印n [3] [3]时,你会得到一些垃圾值。
和* n将打印数组的起始地址。