У вас есть много мелочей, для каждой из которых достаточно вызвать Неопределенное поведение в вашей программе. Для начала, вы должным образом объявляете константу #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
при передаче указателя на массив значений типа double (передача неверного типа для спецификатора формата вызывает Неопределенное поведение ). Вместо этого здесь, чтобы избежать печати десятичных разрядов для значений double
(если они отсутствуют), используйте спецификатор формата %g
вместо %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}};
Таким образом, у вас есть 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
Посмотрите вещи, а также прочитайте мой комментарий о включении предупреждений компилятора и дайте мне знать, если у вас есть дополнительные вопросы.