从 C 中的 fscanf() 初始化时数组值不一致

Inconsistent array values when initialized from fscanf() in C

如果 main() 中的多维数组是从这样的函数指针初始化的:

#include <stdio.h>

void arrayfunction(int (*n)[3][3])
{

(*n)[0][2]=7;

printf("Function output: %i\n", *n[0][2]);

}

main()
{

int y[3][3];

arrayfunction(&y);

printf("Main output: %i \n",y[0][2]);

return(0);

}

然后 main() 中的数组将保存正确的值,但 arrayfunction() 中的指针的输出将不会:

Function output: 4195805
Main output: 7 

但是,如果函数通过fscanf()通过函数指针初始化main()中的数组:

#include <stdio.h>

void readSchedule(int (*s)[3][3]){


FILE *schedule;





schedule=fopen("/var/schedule.conf","r");      

fscanf(schedule,"[%i,%i,%i,%i]\n",s[0][0], s[0][1], s[0][2], s[0][3]); 

fclose(schedule); 

printf("Function output value: %i\n",*s[0][2]);

}

main()
{
int x[3][3];


readSchedule(&x);

printf("Main output value: %i\n ",x[0][2]);

return(0);

}

然后取反,函数局部的指针会输出正确的值,但它在main()中指向的数组不会:

Function output value: 7
Main output value: 0

为什么正确的值在第一个例子中只出现在 main() 局部数组中,而在第二个例子中只出现在函数局部指针中?

检查运算符优先级并注意在 arrayFunction

中使用 n 的两行中的区别
(*n)[0][2]=7;
printf("Function output: %i\n", *n[0][2]);

括号在这里很关键。 [] 运算符的优先级高于 * (http://en.cppreference.com/w/cpp/language/operator_precedence)。如果您在 printf 行中添加括号,您将看到您所期望的结果。

fscanf 示例中或多或少发生了同样的事情。编译器将 s[0][0] 视为指向 int 的指针(像这样 *(s[0][0])),因此数据被写入未定义的区域。

如果您使用像 valgrind 这样的内存调试程序,您会看到大量错误。

第一个例子中的问题在函数内的 printf 语句中指向数组参数的指针的语法中通过更改优先级解决了:

printf("Function output: %i\n", *n[0][2]);

printf("Function output: %i\n", (*n)[0][2]);

在第二个示例中,fscanf() 显然是将值直接填充到 *s[][] 中,而不是间接初始化 *s[][] 指向的 main() 中的数组。所以不是这个:

fscanf(schedule,"[%i,%i,%i,%i]\n",s[0][0], s[0][1], s[0][2], s[0][3]);

语法必须是这样的:

fscanf(schedule,"[%i,%i,%i,%i]\n",&(*s)[0][0], &(*s)[0][1], &(*s)[0][2], &(*s)[0][3]);

为了到达 *s[][] 并将值放在 y[][] 中。