C 通用阵列打印机不适用于doubles类型
老实说,我在这里发疯,试图理解为什么这个通用阵列打印机实现不起作用。它适用于int数组,但不适用于double。我错过了什么C 通用阵列打印机不适用于doubles类型,c,C,老实说,我在这里发疯,试图理解为什么这个通用阵列打印机实现不起作用。它适用于int数组,但不适用于double。我错过了什么 void array_printer(FILE* stream, void* data, size_t data_type_size, size_t nr_rows, size_t nr_cols, char *format){ size_t offset = 0; for (size_t r=0; r<nr_rows;++r){
void array_printer(FILE* stream, void* data, size_t data_type_size, size_t nr_rows, size_t nr_cols, char *format){
size_t offset = 0;
for (size_t r=0; r<nr_rows;++r){
for (size_t c=0; c<nr_cols; ++c){
fprintf(stream,format, *((int8_t*)data + offset*data_type_size));
//fprintf(stream,format, *((char*)data + offset*data_type_size)); // same behaviour
offset++;
}
fprintf(stream,"\n");
}
}
void array_print_double_2D(FILE* stream, double* data, size_t nr_rows, size_t nr_cols){
array_printer(stream, data, sizeof(double), nr_rows, nr_cols, " %lf ");
}
void array_print_int_2D(FILE* stream, int* data, size_t nr_rows, size_t nr_cols){
array_printer(stream, data, sizeof(int), nr_rows, nr_cols, " %d ");
}
int main(){
double *data_double = calloc(12, sizeof(double));
data_double[0] = 1;
data_double[1] = 2;
data_double[2] = 3;
array_print_double_2D(stdout, data_double, 3, 4);
/*
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 what??
0.000000 0.000000 0.000000 0.000000
*/
int*data_int = calloc(12, sizeof(int));
data_int[0] = 1;
data_int[1] = 2;
data_int[2] = 3;
array_print_int_2D(stdout, data_int, 3, 4);
/*
1 2 3 0
0 0 0 0 correct
0 0 0 0
*/
void数组\u打印机(文件*流、void*数据、大小\数据类型\大小、大小\行、大小\列、字符*格式){
尺寸偏差=0;
对于(size\u t r=0;r您正在将内存强制转换为int8\u t*
并取消引用它,您希望得到什么?我会提供某种枚举来区分类型,并在需要时强制转换为正确的类型。您正在将内存强制转换为int8\u t*
并取消引用它,您希望得到什么?我会提供某种枚举以区分类型,并在需要时转换为正确的类型。表达式*(int8_t*)(data+…)
将返回与printf说明符“%lf”不一致的int8_t。这将导致未定义的行为
使用生成打印机的宏可以有效地解决这个问题
#include <stdio.h>
#include <stdlib.h>
#define DEFINE_ARRAY_PRINT_2D(TYPE, FMT) \
void array_print_ ## TYPE ## _2D(FILE* stream, void* data, size_t nr_rows, size_t nr_cols) { \
size_t offset = 0; \
for (size_t r=0; r<nr_rows;++r){ \
for (size_t c=0; c<nr_cols; ++c){ \
fprintf(stream,FMT, ((TYPE*)data)[offset]); \
offset++; \
} \
fprintf(stream,"\n"); \
} \
}
// generate printers
DEFINE_ARRAY_PRINT_2D(int, " %d ")
DEFINE_ARRAY_PRINT_2D(double, " %lf ")
int main(){
double *data_double = calloc(12, sizeof(double));
data_double[0] = 1;
data_double[1] = 2;
data_double[2] = 3;
array_print_double_2D(stdout, data_double, 3, 4);
int *data_int = calloc(12, sizeof(int));
data_int[0] = 1;
data_int[1] = 2;
data_int[2] = 3;
array_print_int_2D(stdout, data_int, 3, 4);
return 0;
}
与预期一样。表达式*(int8_t*)(data+…)
将返回与printf说明符“%lf”不一致的int8_t。这将导致未定义的行为
使用生成打印机的宏可以有效地解决这个问题
#include <stdio.h>
#include <stdlib.h>
#define DEFINE_ARRAY_PRINT_2D(TYPE, FMT) \
void array_print_ ## TYPE ## _2D(FILE* stream, void* data, size_t nr_rows, size_t nr_cols) { \
size_t offset = 0; \
for (size_t r=0; r<nr_rows;++r){ \
for (size_t c=0; c<nr_cols; ++c){ \
fprintf(stream,FMT, ((TYPE*)data)[offset]); \
offset++; \
} \
fprintf(stream,"\n"); \
} \
}
// generate printers
DEFINE_ARRAY_PRINT_2D(int, " %d ")
DEFINE_ARRAY_PRINT_2D(double, " %lf ")
int main(){
double *data_double = calloc(12, sizeof(double));
data_double[0] = 1;
data_double[1] = 2;
data_double[2] = 3;
array_print_double_2D(stdout, data_double, 3, 4);
int *data_int = calloc(12, sizeof(int));
data_int[0] = 1;
data_int[1] = 2;
data_int[2] = 3;
array_print_int_2D(stdout, data_int, 3, 4);
return 0;
}
与预期一样。*(int8_t*)(data+…)
*将*返回与printf说明符“%lf”不一致的int8_t
请尝试使用与intoint8\u t
不匹配的较大整数值,例如256。此外,声明'double*data\u int'有点混乱。您的第二个示例是否应该说int*data\u int
?*(int8\u t*)(data+…)
*将*返回与printf说明符“%lf”不一致的int8\u t
尝试使用与intoint8\t
不匹配的较大整数值,例如256。此外,声明'double*data\u int'有点混乱。您的第二个示例是否应该说int*data\u int
?