【问题标题】:Debug statements for a 4x4 matrix4x4 矩阵的调试语句
【发布时间】:2009-10-04 12:59:31
【问题描述】:

我正在打印 4x4 矩阵的调试语句。有谁知道不使用cout 的更好方法?

// num decimal places to show
void print( int decimals )
{
    char fmtString[ 300 ] ;

    // I'm thinking this should be able to get smaller.
    sprintf(fmtString,
            "%%.%df %%.%df %%.%df %%.%df\n"
            "%%.%df %%.%df %%.%df %%.%df\n"
            "%%.%df %%.%df %%.%df %%.%df\n"
            "%%.%df %%.%df %%.%df %%.%df",
            decimals, decimals, decimals, decimals, 
            decimals, decimals, decimals, decimals, 
            decimals, decimals, decimals, decimals, 
            decimals, decimals, decimals, decimals ) ;

    printf(fmtString,
           m[0][0], m[0][1], m[0][2], m[0][3],
           m[1][0], m[1][1], m[1][2], m[1][3],
           m[2][0], m[2][1], m[2][2], m[2][3],
           m[3][0], m[3][1], m[3][2], m[3][3] ) ;
}

预处理器的超级奖励积分!

【问题讨论】:

  • 你不想要 couts 并且你想要聪明?听起来很矛盾。
  • 他不想要聪明,他想要更聪明。
  • 你在哪里声明了m?为什么不写一个以矩阵为参数的函数呢?
  • 为什么是300? (您是否有机会编写 Web 服务器?如果是,那您就错了:运行良好的 Web 服务器不需要内置缓冲区溢出。)
  • 它不能在 C 中正常工作。 C 没有默认参数。

标签: c


【解决方案1】:

怎么样:

void print( int decimals = 2 )
{
    int dimension = 4;
    for(int i = 0; i < dimension; i++) {
        for(int j = 0; j < dimension; j++) {
            printf("%.*f", decimals, matrix[i][j]);
            if(j == dimension - 1) printf("\n");
            else                   printf(" ");
        }
    }
}

【讨论】:

  • pfff.... 如果你要走那条路,你不应该停在那里,做 printf("%.*f%c", decimals, matrix[i][j], (j==3)?'\n':''); :-)
  • 为什么如果(j == 3)?!如果(j == 维度-1)!
  • @EFraim:你是对的,当然。固定的。 @fvu:走哪条路?
【解决方案2】:

(wo)人说,基于预处理器的解决方案的超级奖励积分。我们开始了,非常感谢所有帮助我实现这一目标的人。

#include <stdlib.h>
#include <stdio.h>

#define MADU(matrix,decimals,dimension) ({ \
    for(int i = 0; i < dimension; i++) { \
        for(int j = 0; j < dimension; j++) { \
            printf("%.*f%c", decimals, matrix[i][j],(j==dimension-1)?'\n':' '); \
        } \
    } \
})

/*
 * 
 */
int main(int argc, char** argv) {
    double a[4][4];

    MADU(a,2,4);

    return (EXIT_SUCCESS);
}

请注意,这并不能真正反映我所说的好的解决方案。

【讨论】:

    【解决方案3】:

    这个方法很简单,把cout换成printf就行了!虽然我更喜欢 C++ 流,因为它们更优雅 IMO:

    #include <iostream>
    #include <iomanip>
    
    template <std::size_t rows, std::size_t columns>
    void printMatrix(double (&matrix)[rows][columns], int dec)
    {
        std::cout << std::fixed << std::setprecision(dec);
        for(std::size_t r = 0; r < rows; r++)
        {
            for(std::size_t c = 0; c < columns; c++)
            {
                std::cout << matrix[r][c] << '\t';
            }
            std::cout << '\n';
        }
    }
    
    int main()
    {
        double matrix[4][4];
    
        printMatrix(matrix, 2);
    }
    

    【讨论】:

    • 如果将 cout 替换为 printf,std::setprecision 将如何工作?
    • 他必须想办法,我不知道/使用 printf 样式函数 :)
    【解决方案4】:

    如何找到一种不受矩阵大小限制的方法?您必须为 5x5、6x6...nxn 矩阵重写整个方法。更好的方法?为什么不在所有行和列上嵌套循环?我绝对不会使用 C 风格的打印,因为我不想处理创建格式化字符串。只需使用 cout 流即可。

    我还建议您传入要打印的矩阵,以保持通用性,或者将此作为 Matrix 类的方法,以便对其数据成员进行操作。你确实有一个矩阵类,不是吗?如果我没记错的话,C++ 是一种面向对象的语言。

    【讨论】:

    • C++ 是一种多范式语言。它支持 OOP 结构。
    • 是的,我知道。我的观点是,如果你正在编写可以从对象和抽象中受益的东西,比如矩阵,你为什么不想使用它们?
    【解决方案5】:

    C 中,没有默认参数。我也不喜欢全局变量,所以我把m做了个参数。

    #include <stdio.h>
    void print(double *m, int decs) {
      int k;
      for (k=0; k<16; k++) {
        printf("%.*f", decs, *m++);
        if (k%4 == 3) puts("");
        else putchar(' ');
      }
    }
    
    int main(void) {
      double m[4][4] = {{1/5,1/6,1/9,-1/4}, {0,1/4,-1/7,1/16},
                        {1/2,-1/2,1/3,-1/3}, {1/1,1/2,1/3,1/4}};
      print(&m[0][0], 2);
      return 0;
    }
    

    编辑:传入参数的大小

    #include <stdio.h>
    void print(double *m, int cols, int rows, int decs) {
      int k, s = cols*rows;
      for (k = 0; k < s; k++) {
        printf("%.*f", decs, *m++);
        if ((k + 1) % cols) putchar(' ');
        else                puts("");
      }
    }
    
    int main(void) {
      double m[4][4] = {{1/5,1/6,1/9,-1/4}, {0,1/4,-1/7,1/16},
                        {1/2,-1/2,1/3,-1/3}, {1/1,1/2,1/3,1/4}};
      print(&m[0][0], 4, 4, 2);
      return 0;
    }
    

    【讨论】:

      【解决方案6】:

      预处理器?这实际上听起来像是一个挑战。想知道 Boost.Preprocessor 是否与 C 兼容,但我看不出它不应该的任何原因。警告,我不会打扰包含或“换行”标记;)

       // The formatting of sprintf
       #define PRINT_FORMAT_ELEM(z,n,data) // data is the nbColumns (or -1)
         BOOST_PP_EXPR_IF(
           BOOST_PP_EQUAL(
             BOOST_PP_ADD(n, 1),
             data
           ),
           "%%.%%df\n",
           "%%.%%df "
         )
      
       #define PRINT_FORMAT_LINE(z,n,data) // data is (nbRows, nbColumns)
         BOOST_PP_REPEAT(
           data,
           PRINT_FORMAT_ELEM,
           BOOST_PP_EXPR_IF(
             BOOST_PP_EQUAL(
               BOOST_PP_ADD(n, 1),
               BOOST_PP_TUPLE_ELEM(2,0,data)
             ),
             -1, // no \n on the last line
             BOOST_PP_TUPLE_ELEM(2,1,data)
           )
         )
      
      
       #define PRINT_FORMAT(nbRows, nbColumns)
         BOOST_PP_REPEAT(
           nbRows,
           PRINT_FORMAT_LINE,
           (nbRows, nbColumns)
         )
      
      
       // The decimals
       #define PRINT_MATRIX_ELEM(z,n,data) // data is (decimals, notLastRow, nbColumns)
         BOOST_PP_ELEM(3, 0, data)
         BOOST_PP_COMMA_IF(
           BOOST_PP_AND(
             BOOST_PP_TUPLE_ELEM(3, 1, data),
             BOOST_PP_NOT_EQUAL(
               BOOST_PP_ADD(n,1),
               BOOST_PP_TUPLE_ELEM(3, 2, data)
             )
           )
         )
      
       #define PRINT_DECIMAL_LINE(z, n, data) // data is (decimals, nbRows, nbColumns)
         BOOST_PP_REPEAT(
           BOOST_PP_TUPLE_ELEM(3, 2, data),
           PRINT_MATRIX_ELEM,
           (
             BOOST_PP_TUPLE_ELEM(3, 0, data),
             BOOST_PP_NOT_EQUAL(
               BOOST_PP_ADD(n,1),
               BOOST_PP_TUPLE_ELEM(3, 1, data)
             ),
             BOOST_PP_TUPLE_ELEM(3, 2, data)
           )
         )
      
       #define PRINT_DECIMALS(decimals, nbRows, nbColumns)
         BOOST_PP_REPEAT(
           nbRows,
           PRINT_DECIMAL_LINE,
           (decimals, nbRows, nbColumns)
         )
      
      
       // The matrix itself
       #define PRINT_MATRIX_LINE(z, n, data) // data is (name, nbRows, nbColumns)
         BOOST_PP_REPEAT(
           BOOST_PP_TUPLE_ELEM(3, 2, data),
           PRINT_MATRIX_ELEM,
           (
             BOOST_PP_TUPLE_ELEM(3, 0, data)[n],
             BOOST_PP_NOT_EQUAL(
               BOOST_PP_ADD(n,1),
               BOOST_PP_TUPLE_ELEM(3, 1, data)
             ),
             BOOST_PP_TUPLE_ELEM(3, 2, data)
           )
         )
      
       #define PRINT_MATRIX_IMPL(name, nbRows, nbColumns)
          BOOST_PP_REPEAT(
            nbRows,
            PRINT_MATRIX_LINE,
            (name, nbRows, nbColumns)
          )
      
      
       // And the whole thing
       #define PRINT_MATRIX(string, decimals, name, nbRows, nbColumns)
         sprintf(string,
           PRINT_FORMAT(nbRows, nbColumns),
           PRINT_DECIMALS(decimals, nbRows, nbColumns)
         );
      
         printf(string,
                PRINT_MATRIX_IMPL(name, nbRows, nbColumns)
         )
      
      
       // And now your code:
       void print(int decimals)
       {
         char fmtString[300];
      
         PRINT_MATRIX(fmtString, decimals, m, 4, 4);
       }
      

      任何人都可以帮助进行代码审查;)?

      【讨论】:

        猜你喜欢
        • 2010-11-12
        • 2017-08-21
        • 2014-11-13
        • 1970-01-01
        • 2021-03-19
        • 2012-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多