gpt4 book ai didi

c - 如何将 (void**) 传递给函数并有效地取消引用/使用任何类型?

转载 作者:太空宇宙 更新时间:2023-11-04 00:11:16 25 4
gpt4 key购买 nike

使用一个简单的函数来打印一个模拟的二维矩阵,我只是希望能够将一个指针数组传递给该函数作为void**,以及所需的维度m x nsizeof 类型printf格式字符串,以及区分 float -从整数。我遇到的问题是处理取消引用指针数组的范围,以便每个元素都可以正确打印为原始类型。下面,基本方案是:

void mtrx_prnv (size_t m, size_t n, void **matrix,
size_t sz, char *fmt, char fp)
{
if (fp) { // floating point
if (sz == 4) {
float **mtrx = (float **)matrix;
...
}
else if (sz == 8) {
double **mtrx = (double **)matrix;
...
}
}
else {
if (sz == 1) {
char **mtrx = (char **)matrix;
...
}
else if (sz == 2) {
...
}
...
}
}

该方法工作正常,但问题是在测试浮点标志 'fp' 和 sizeof 类型 'sz' 之后,任何要使用的指针创建因为取消引用仅限于测试 block 的范围,最终需要对处理每个 block 中的指针数组所需的代码进行基本的逐字复制。代码最终比为每种类型创建许多小函数要长。例如:

void mtrx_prn_float (size_t m, size_t n, float **matrix) {}

void mtrx_prn_int (size_t m, size_t n, int **matrix) {}

是否有更好或标准的方法将指针数组传递给 void** 类型、sizeof 类型以及正确取消引用类型所需的任何其他标志,而无需重复代码?如果这是必须的方式,那很好,但我想确保我没有错过一个简单的技巧。到目前为止,我的搜索没有产生任何有用的结果(搜索返回的大量信息是关于如何取回单一类型,而不是分离所有类型)。 How to write C function accepting (one) argument of any type此处不正确。

完整的函数(没有用于 int/unsigned 分离的附加逻辑)如下。

/* printf array of pointers to type as 2D matrix of
size 'm x n' with sizeof type 'sz', format string
'fmt' and floating point flag 'fp' (0 - int).
*/
void mtrx_prnv (size_t m, size_t n, void **matrix,
size_t sz, char *fmt, char fp)
{
register size_t i, j;

if (fp) { /* floating point */

if (sz == 4) {
float **mtrx = (float **)matrix;
for (i = 0; i < m; i++) {
char *pad = " [ ";
for (j = 0; j < n; j++) {
printf (fmt, pad, mtrx[i][j]);
pad = ", ";
}
printf ("%s", " ]\n");
}
}
else if (sz == 8) {
double **mtrx = (double **)matrix;
for (i = 0; i < m; i++) {
char *pad = " [ ";
for (j = 0; j < n; j++) {
printf (fmt, pad, mtrx[i][j]);
pad = ", ";
}
printf ("%s", " ]\n");
}
}
else
goto err;
}
else { /* integer (no unsigned yet) */

if (sz == 1) {
char **mtrx = (char **)matrix;
for (i = 0; i < m; i++) {
char *pad = " [ ";
for (j = 0; j < n; j++) {
printf (fmt, pad, mtrx[i][j]);
pad = ", ";
}
printf ("%s", " ]\n");
}
}
else if (sz == 2) {
short **mtrx = (short **)matrix;
for (i = 0; i < m; i++) {
char *pad = " [ ";
for (j = 0; j < n; j++) {
printf (fmt, pad, mtrx[i][j]);
pad = ", ";
}
printf ("%s", " ]\n");
}
}
else if (sz == 4) {
int **mtrx = (int **)matrix;
for (i = 0; i < m; i++) {
char *pad = " [ ";
for (j = 0; j < n; j++) {
printf (fmt, pad, mtrx[i][j]);
pad = ", ";
}
printf ("%s", " ]\n");
}
}
else if (sz == 8) {
long **mtrx = (long **)matrix;
for (i = 0; i < m; i++) {
char *pad = " [ ";
for (j = 0; j < n; j++) {
printf (fmt, pad, mtrx[i][j]);
pad = ", ";
}
printf ("%s", " ]\n");
}
}
else
goto err;
}

return;

err:;

fprintf (stderr, "%s() error: invalid size for fp_flag '%zu'.\n",
__func__, sz);
}

根据评论中的建议,声明/定义更新为:

void mtrx_prnv (size_t m, size_t n, void *matrix,
size_t sz, char *fmt, char fp);

宏提供的解决方案

有几个很好的解决方案,主要是通过为冗余文本创建宏来消除逐字​​重复,其次是使用回调来打印元素的值。宏提供了接近下降的解决方案:

#define PRINT_MATRIX(type) do { \
type **mtrx = (type **)matrix; \
for (i = 0; i < m; i++) { \
char *pad = " [ "; \
for (j = 0; j < n; j++) { \
printf (fmt, pad, mtrx[i][j]); \
pad = ", "; \
} \
printf ("%s", " ]\n"); \
} \
} while (0)

...

void mtrx_prnvm (size_t m, size_t n, void *matrix,
size_t sz, char *fmt, char fp)
{
register size_t i, j;

if (fp) { /* floating point */

if (sz == 4) {
PRINT_MATRIX(float);
}
else if (sz == 8) {
PRINT_MATRIX(double);
}
else
goto err;
}
else { /* integer (no unsigned yet) */

if (sz == 1) {
PRINT_MATRIX(char);
}
else if (sz == 2) {
PRINT_MATRIX(short);
}
else if (sz == 4) {
PRINT_MATRIX(int);
}
else if (sz == 8) {
PRINT_MATRIX(long);
}
else
goto err;
}

return;

err:;

fprintf (stderr, "%s() error: invalid size for fp_flag '%zu'.\n",
__func__, sz);
}

最佳答案

考虑到您要逐字重复每个 block 的大部分内容,一个明显的解决方案是定义和使用表示该代码的宏(而不是另一个答案建议的用于生成每种类型函数的宏)。这将限制物理代码重复,并且不需要您更改程序的结构:

#define PRINT_MATRIX(type) do { \
(type) **mtrx = ((type) **)matrix;
for (i = 0; i < m; i++) { \
char *pad = " [ "; \
for (j = 0; j < n; j++) { \
printf (fmt, pad, mtrx[i][j]); \
pad = ", "; \
} \
printf ("%s", " ]\n"); \
} \
} while (0)

void mtrx_prnv (size_t m, size_t n, void *matrix,
size_t sz, char *fmt, char fp)
{
if (fp) { // floating point
if (sz == 4) {
PRINT_MATRIX(float);
}
else if (sz == 8) {
PRINT_MATRIX(double);
}
}
else {
if (sz == 1) {
PRINT_MATRIX(char);
}
else if (sz == 2) {
PRINT_MATRIX(short);
}
...
}
}

关于c - 如何将 (void**) 传递给函数并有效地取消引用/使用任何类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33246740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com