我试图定义用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作为参数接收,但它有bug。
我的问题是:
1 - 为什么不对?
2 - 如何让这个宏工作正常? (如果有必要,解决方案可能包含1或2个宏声明,但是短声明,否则我不会问,我可以为int创建一个宏,为char设置其他宏。
PS:这个宏写成一行,上面的算法只是为了显示它的作用。
由于
答案 0 :(得分:4)
如果你真的必须为此制作一个宏 - 正如其他人所指出的那样,这是一个真正糟糕的想法而不是正确的方法 - 你遇到的问题是该宏由预处理器解释,它将换行符视为宏替换的结束。要解决这个问题,你需要在行的末尾引入一些转义序列:
#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]);
请注意,我已经考虑从字符串内部使用令牌粘贴运算符,因为预处理器不会为您填充字符串文字,而是选择使用字符串化运算符{{1}将类型转换为字符串文字。由于编译器会自动将相邻的字符串文字连接在一起,因此无需粘贴任何内容。我应该重复这是一个非常糟糕的想法,因为它会损害代码的可读性,并且不提供任何你不能用常规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);
或
double
的数组
cin
从外部文件中读取int arr[5][5];
ifstream input("my-file.txt");
readArray(arr, input);
的数组。这是类型安全的,如果在未定义数组大小或无法读取类型的情况下尝试读取,则会引发编译器错误。这可以防止各种可能的问题。将其与您的宏进行比较,我可以在这里执行以下操作:
int
糟糕 - 我只使用了错误的数组大小和错误的int arr[5][5];
rm(arr, 6, 6, f);
说明符。任何时候你可以将工作卸载到编译器,使你不必在很多地方进行代码更改,这是值得考虑的!