#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define N 8
typedef struct Array {
double element[N][N];
} Array;
void PrintArray(Array a) {
int i;
int j;
for (i = 0; i < 64; i++) {
for (j = 0; j < 64; j++) {
printf("%d ", a.element);
}
} // for
} // PrintArray
int main(int argc, const char *argv[]) {
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 }
};
// need to implement PrintArray
PrintArray(M);
return EXIT_SUCCESS;
}
答案 0 :(得分:3)
您有很多小东西,每个小东西足以在程序中调用未定义行为。对于初学者,您可以正确地声明常量#define N 8
,但是在遍历要打印的数组中的常量时忽略常量,例如
#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 ) format-specifier调用未定义行为)。相反,在这里,为了避免打印double
值的小数位数(除非存在),请使用%g
format-specifier 而不是%d
(仅用于整数转换,并且可能甚至与尝试打印的字节数不同)。
使用您定义的常量(并在修复了初始化和格式说明符之后),您可以执行以下操作:
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
变量名,而推荐使用所有 lower- case ,同时保留大写名称供宏和常量使用。)
此外,在C语言中,您将希望将 pointer 传递给结构,而不是结构本身。与传递整个结构本身的副本相反,这仅允许在每个函数调用中传递价值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]
。
要初始化2D数组,初始化为type array[N][N] = {{0 ... N-1}, {1 ... N-1}, ... {N-1 ... N-1}};
,因此,结构内数组需要3个花括号,例如Array M = {{{0...N-1}, {1...N-1}, {...}}}
。
同时放置该结构的初始化及其包含的2D数组将导致类似于以下内容的初始化:
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
仔细研究,并阅读我对启用编译器警告的评论,并让我知道您是否还有其他问题。
答案 1 :(得分:1)
通知:
"%d"
或"%i"
:
%e
(%E
)浮点或双指数格式%f
浮点或双符号十进制%g
(%G
)浮动或根据需要重复使用%f
或%e
8x8
,因此请在循环中使用N
常量。[i][j]
打印。尝试一下:
void PrintArray(Array a){
int i;
int j;
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
{
printf("%g ", a.element[i][j]);
}
printf("\n");
}
}
输出如下:
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
对于数字"%d"
使用"%g"
而不是double
的输出具有未定义的行为,因此它可能输出0
或实数值:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0