你有很多小东西,每一个都足以在你的程序中调用未定义的行为。对于初学者,您可以正确声明常量#define N 8,然后在遍历您的array-within-a-struct 以打印时忽略该常量,例如
#define N 8
...
void PrintArray(Array a){
...
for (i=0; i<64; i++){
for (j=0; j<64; j++){
您只有一个 8x8 双精度数组。然后,当您尝试迭代 4096 次而不是 64 次时-您远远超出了数组范围(除非您的 a.element 实际上并没有访问数组的任何元素-因此您完全愚蠢地避免了未定义的行为-运气...)
但是,在传递指向双精度数组的指针时,您确实使用 %d 的 format-specifier 调用 Undefined Behavior(传递格式不正确的类型-说明符调用未定义的行为)。相反,在这里,为了避免打印 double 值(除非存在)的小数位,请使用 %g format-specifier 而不是 %d(用于 integer 仅转换,甚至可能与您尝试打印的字节数不同)。
使用您定义的常量(并在修复初始化和格式说明符之后),您可以这样做:
void print_array (Array a)
{
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
printf (" %3g ", a.element[i][j]); /* note the use of i & j */
putchar ('\n');
}
}
(注意:虽然不是错误,但 C 的标准编码风格避免使用 camelCase 或 MixedCase 变量名,而支持所有小写 同时保留 大写 名称以用于宏和常量。)
此外,在 C 中,您需要将 指针 传递给结构,而不是结构本身。这允许在每个函数调用上仅传递 sizeof (a_pointer) 的信息,而不是传递整个结构本身的副本。所以你的print_array 函数可以更恰当地写成:
void print_array (Array *a)
{
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
printf (" %3g ", a->element[i][j]); /* note the use of -> */
putchar ('\n');
}
}
(注意:要在main() 中传递结构的地址,您可以将print_array 称为print_array (&M);)
您对Q50 和M 的初始化都是错误的。你使用:
Array Q50 = {{18, 11, 10, 18, 26, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 18, 26, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68,109,103, 77,
26, 35, 55, 64, 81,104,113, 92,
49, 64, 78, 87,103,121,120,101,
72, 92, 95, 98,112,100,103, 99}
};
(你的编译器应该对你发出警告——你需要阅读、理解和修复——并且在编译干净之前不要接受代码——没有警告)
struct foo 的基本初始化是 struct foo = { .... },其中 { ... } 的内容可以使用 named-initializer 或为结构的部分或所有成员提供值。在这里,您的struct 有一个成员或输入double [N][N]。
要初始化一个二维数组,初始化是type array[N][N] = {{0 ... N-1}, {1 ... N-1}, ... {N-1 ... N-1}}; 所以你的array-within-a-struct 需要3个大括号,例如Array M = {{{0...N-1}, {1...N-1}, {...}}}.
将结构的初始化和它包含的二维数组都放入将导致初始化类似于:
Array M = {{{174, 143, 143, 143, 143, 143, 143, 156},
{192, 200, 156, 174, 174, 174, 156, 110},
{254, 198, 174, 174, 200, 174, 143, 143},
{239, 200, 156, 200, 200, 166, 143, 143},
{200, 174, 156, 167, 166, 149, 156, 156},
{128, 156, 143, 156, 174, 200, 198, 174},
{143, 105, 110, 149, 156, 156, 200, 166},
{110, 156, 143, 143, 143, 156, 174, 156}}};
总而言之,您可以执行类似以下的操作:
#include <stdio.h>
#define N 8
typedef struct Array {
double element[N][N];
} Array;
void print_array (Array a)
{
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
printf (" %3g ", a.element[i][j]);
putchar ('\n');
}
}
Array Q50 = {{{18, 11, 10, 18, 26, 40, 51, 61},
{12, 12, 14, 19, 26, 58, 60, 55},
{14, 13, 18, 26, 40, 57, 69, 56},
{14, 17, 22, 29, 51, 87, 80, 62},
{18, 22, 37, 56, 68,109,103, 77},
{26, 35, 55, 64, 81,104,113, 92},
{49, 64, 78, 87,103,121,120,101},
{72, 92, 95, 98,112,100,103, 99}}};
int main (void)
{
Array M = {{{174, 143, 143, 143, 143, 143, 143, 156},
{192, 200, 156, 174, 174, 174, 156, 110},
{254, 198, 174, 174, 200, 174, 143, 143},
{239, 200, 156, 200, 200, 166, 143, 143},
{200, 174, 156, 167, 166, 149, 156, 156},
{128, 156, 143, 156, 174, 200, 198, 174},
{143, 105, 110, 149, 156, 156, 200, 166},
{110, 156, 143, 143, 143, 156, 174, 156}}};
puts ("\nprinting M\n");
print_array (M);
puts ("\nprinting Q50\n");
print_array (Q50);
return 0;
}
使用/输出示例
$ ./bin/structarrayq50
printing M
174 143 143 143 143 143 143 156
192 200 156 174 174 174 156 110
254 198 174 174 200 174 143 143
239 200 156 200 200 166 143 143
200 174 156 167 166 149 156 156
128 156 143 156 174 200 198 174
143 105 110 149 156 156 200 166
110 156 143 143 143 156 174 156
printing Q50
18 11 10 18 26 40 51 61
12 12 14 19 26 58 60 55
14 13 18 26 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
26 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99
检查一下,并阅读我关于启用编译器警告的评论,如果您还有其他问题,请告诉我。