Jack D
Jack D

Reputation: 15

printf won't print double type array values

#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

Answers (2)

Notice:

  1. You should use below specifiers for printing your array, not "%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 required
  2. You have 2d array with 8x8 dimension, so use of N constant in your loop.
  3. Also select array element to print it using [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

David C. Rankin
David C. Rankin

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

Related Questions