printf不会打印双类型数组值

问题描述 投票:2回答:2
#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;
}
c arrays struct printf double
2个回答
1
投票

注意:

  1. 你应该使用下面的说明符来打印你的数组,而不是"%d""%i"%e%E)浮点数或双指数格式 %f浮点数或双重十进制 %g%G)根据需要浮动或双重使用%f%e
  2. 你有2d数组与8x8维度,所以在循环中使用N常量。
  3. 还要选择数组元素以使用[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

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的格式说明符调用未定义行为(为格式说明符传递不正确的类型会调用未定义的行为)。相反,在这里,为了避免double值的小数位打印(除非存在),使用%g格式说明符而不是%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的标准编码风格避免使用camelCaseMixedCase变量名来支持所有小写,同时保留用于宏和常量的大写名称。)

另外,在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);

你对Q50M的初始化都是错误的。你用:

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 = { .... },其中{ ... }的内容可以使用命名初始化程序或为结构的某些或所有成员提供值。在这里,你有一个成员为你的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}, {...}}}

同时对struct进行初始化以及它包含的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

仔细阅读,阅读关于启用编译器警告的评论,如果您有其他问题,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.