【问题标题】:Macro for reading matrix C++用于读取矩阵 C++ 的宏
【发布时间】:2016-06-29 22:04:39
【问题描述】:

我正在尝试定义宏以在 C++ 中读取和打印矩阵,但我尝试了一些不同的方法,但它不起作用:

#define rm(A, m, n, type) 
    for(int i = 0; i < m; i++) 
        for(int j = 0; j < n; j++) 
            scanf("%##type##", &A[i][j]);

A 是矩阵(int 或 char)

我想写 d 或 c 来读取 int 或 char,但这段代码不起作用,我什至不知道为什么,我只是尝试使用 concat ## 符号来创建 scanf 接收的字符串论据,但它有错误。

我的问题是:

1 - 为什么错了?

2 - 我怎样才能使这个宏正常工作? (如有必要,解决方案可能包含 1 或 2 个宏声明,但很短,否则我不会问,我可以为 int 创建一个宏,为 char 创建其他宏。

PS:这个宏写了一行,上面的算法只是为了展示它的作用。

谢谢

【问题讨论】:

  • 宏是邪恶的。使其成为内联函数。例如,宏允许您将“hello”作为一个参数传递,将“Frog”作为类型传递。
  • 顺便说一句,使用花括号 {} 不会影响运行时并且对编译的影响可以忽略不计。使用它们。这是一种减少缺陷的方法。
  • 我认为问题在于替换字符文字。您可能必须传递整个 scanf 格式字符串。
  • 不要费心阅读第二个矩阵。这个系列在第一个之后真的走下坡路了。

标签: c++ macros


【解决方案1】:

如果您真的必须为此创建一个宏 - 正如其他人所指出的那样,这是一个非常糟糕的想法,而不是正确的方法 - 您遇到的问题是该宏由预处理器解释,它将换行符视为宏替换的结束。要解决此问题,您需要在行尾引入一些转义序列:

#define rm(A, m, n, type) \
    for(int i = 0; i < m; i++) \
        for(int j = 0; j < n; j++) \
            scanf("%" #type, &A[i][j]);

请注意,我已经从字符串内部排除了您对令牌粘贴运算符的使用,因为预处理器不会为您填写字符串文字,而是选择使用字符串化运算符 # 来将类型转换为字符串文字。由于编译器会自动将相邻的字符串文字连接在一起,因此无需粘贴任何内容。我应该重申这是一个非常糟糕的主意,因为它会损害代码的可读性,并且不能提供常规 C++ 函数无法提供的任何功能。

不过,您已将此问题标记为 C++,因此我应该指出,scanf 可能会出现各种类型安全问题,因此使用 iostream 库几乎可以肯定更安全,该库用于它的所有错误都会在编译时捕获大量可能的错误。

不过,从根本上说,您不应该为此使用宏。只需编写一个常规的旧函数。这是执行此操作的一种方法,它具有自动推断数组大小的额外好处:

template <typename T, size_t m, size_t n>
void readArray(T (&array)[m][n], std::istream& source = std::cin) {
   for (size_t i = 0; i < m; i++) {
      for (size_t j = 0; j < n; j++) {
          source >> array[i][j];
      }
   }
}

现在,你可以这样说:

double arr[137][42];
readArray(arr);

cin 中读取doubles 的数组,或者

int arr[5][5];
ifstream input("my-file.txt");
readArray(arr, input);

从外部文件中读取ints 的数组。这是类型安全的,如果您在未定义数组大小或无法读取类型的情况下尝试读取,则会引发编译器错误。这可以防止各种可能的问题。将此与您的宏进行比较,我可以在其中执行以下操作:

int arr[5][5];
rm(arr, 6, 6, f);

糟糕 - 我只是使用了错误的数组大小和错误的 scanf 说明符。任何时候您都可以将工作卸载到编译器,从而使您不必在很多地方进行代码更改,这是值得考虑的!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2017-08-20
    • 2022-12-19
    • 1970-01-01
    • 2015-09-06
    • 2011-01-14
    相关资源
    最近更新 更多