Reputation: 15
#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;
}
Upvotes: 2
Views: 2090
Reputation: 4111
Notice:
"%d"
or "%i"
:
%e
(%E
) float or double exponential format%f
float or double signed decimal%g
(%G
) float or double use %f
or %e
as required8x8
dimension, so use of N
constant in your loop.[i][j]
.Try this :
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");
}
}
Output is as follows:
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
The output while using "%d"
instead of "%g"
for double
number has undefined behavior, so it may print 0
or real values :
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
Upvotes: 1
Reputation: 84559
You have a lot of little things where each is enough to invoke Undefined Behavior in your program. For starters, you properly declare the constant #define N 8
, but then ignore the constant when iterating over your array-within-a-struct to print, e.g.
#define N 8
...
void PrintArray(Array a){
...
for (i=0; i<64; i++){
for (j=0; j<64; j++){
You only have an 8x8
array of doubles. When you then attempt to iterate 4096
times instead of 64
times -- you are well outside your array bounds (except your a.element
doesn't actually access any element of the array - so you avoided undefined behavior by sheer dumb-luck...)
However, you do invoke Undefined Behavior with your format-specifier of %d
when passing a pointer to array of doubles (passing an incorrect type for the format-specifier invokes Undefined Behavior). Instead, here, to avoid the decimal places printing for the double
values (unless present), use the %g
format-specifier instead of the %d
(which is for integer conversions only and is likely not even the same number of bytes as what you attempted to print).
Using the constant you define (and after fixing your initializations and format specifier), you could do:
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');
}
}
(note: While not an error, the standard coding style for C avoids the use of camelCase
or MixedCase
variable names in favor of all lower-case while reserving upper-case names for use with macros and constants.)
Additionally, in C, you will want to pass a pointer to the struct, instead of the struct itself. This allows passing only the sizeof (a_pointer)
worth of information on each function call as opposed to passing a copy of the entire structure itself. So your print_array
function could more properly be written as:
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');
}
}
(note: to pass the address of the struct in main()
you would call print_array
as, e.g. print_array (&M);
)
Your initialization of both Q50
and M
are wrong. You use:
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}
};
(your compiler should be screaming warnings at you -- which you need to read, understand and fix -- and do not accept code until it compiles cleanly -- without warning)
The basic initialization for struct foo
is struct foo = { .... }
where the contents of { ... }
can make use of a named-initializer or provide values for some, or all members of your struct. Here, you have a single member for your struct
or type double [N][N]
.
To initialize an 2D array, the initialization is type array[N][N] = {{0 ... N-1}, {1 ... N-1}, ... {N-1 ... N-1}};
So you have 3-braces required for your array-within-a-struct, e.g. Array M = {{{0...N-1}, {1...N-1}, {...}}}
.
Putting both the initialization for the struct, and the 2D array it contains would result in an initialization similar to:
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}}};
Putting it altogether, you could do something similar to the following:
#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;
}
Example Use/Output
$ ./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
Look things over, as well as reading my comment about enabling compiler-warnings and let me know if you have further questions.
Upvotes: 3