问候语,
等级:从初级到中级之间
这是我的候选阵列打印功能:
(>>= uncurry ((. pure) . (:)))
我试图让它与平台无关。它适用于我的项目。我想知道如果它包含在标准C库中,这个函数会产生什么样的问题。而且,为什么C库中没有阵列打印功能?
感谢。
答案 0 :(得分:0)
从技术上讲,没有什么能阻止int与其他东西的大小相同,例如我相信x64 int和float的大小完全相同。 C无论如何都没有内置它,我建议将类型作为特定代码传递,然后从那里打印阵列。
void print_array(void *arr, size_t len, int type){
//handle print here
}
其中type参数可以具有不同类型的不同值。另请注意,使用size_t而不是int来保存数组的长度。
您也可以使用宏来执行此操作,您可以执行类似
的操作#define DEF_NEW_ARRAY(TYPE, TYPE_NAME)
typedef struct TYPE_NAME{
TYPE *arr;
size_t len;
} TYPE_NAME;
void TYPENAME##_print(TYPE_NAME *arr){
//define your function
}
那么你可以这样使用这个宏
DEF_NEW_ARRAY(int, int_arr)
int_arr x;
之后您可以初始化数组并打印您的值等。
C11还介绍了_Generic
。你可以在这里阅读它
答案 1 :(得分:0)
您可以关注qsort
模型并传递委托函数来处理实际格式:
void print_array( void *array, size_t arrsize, size_t eltsize, const char *(*fmt)( const void *item ) )
{
unsigned char *cur = array;
fprintf( stdout, "{" );
if ( arrsize > 0 )
{
fprintf( stdout, "%s", fmt( cur ) );
cur += eltsize;
for ( size_t i = 1; i < arrsize; i++ )
{
fprintf( stdout, ", %s", fmt( cur ) );
cur += eltsize;
}
}
fprintf( stdout, "}" );
}
如果要打印出整数数组,可以为整数创建格式化函数并将其传递给print_array
:
const char *intFmt( const void *item )
{
static char buffer[12];
sprintf( buffer, "%d", *(const int *) item );
return buffer;
}
如果要打印双打数组,可以创建不同的格式化功能:
const char *dblFmt( const void *item )
{
static char buffer[12];
sprintf( buffer, "%10.2f", *(const double *) item );
return buffer;
}
您可以为聚合类型(结构,联合,其他数组),枚举等创建格式化程序,为您提供几乎无限的灵活性。此外,通过将类型感知内容委托给格式化程序,您的print_array
函数本身也很简单;每次想要支持新类型时,都不必破解它。
这种方法有缺点。对于给定类型使用错误的格式化程序时,编译器无法向您发出警告(只要您使用void *
进行处理,就会在窗口中抛出类型安全性)。此外,在此实现中,我在格式化程序中使用静态缓冲区,使它们不可重入且不是线程安全的。最好将目标缓冲区传递给print_array
(它将传递给格式化程序),但我试图让这个例子保持可读性。
您可能还希望将输出流作为参数传递,而不是始终打印到stdout
。
但是,这至少应该让你了解可能的情况。这是一个完整的实现,以及一些示例输出:
#include <stdio.h>
void print_array( void *array, size_t arrsize, size_t eltsize, const char *(*fmt)( const void *item ) )
{
unsigned char *cur = array;
fprintf( stdout, "{" );
if ( arrsize > 0 )
{
fprintf( stdout, "%s", fmt( cur ) );
cur += eltsize;
for ( size_t i = 1; i < arrsize; i++ )
{
fprintf( stdout, ", %s", fmt( cur ) );
cur += eltsize;
}
}
fprintf( stdout, "}" );
}
const char *intFmt( const void *item )
{
static char buffer[12];
sprintf( buffer, "%d", *(const int *) item );
return buffer;
}
const char *dblFmt( const void *item )
{
static char buffer[12];
sprintf( buffer, "%10.2f", *(const double *) item );
return buffer;
}
struct node {
int val;
struct node *next;
};
const char *nodeFmt( const void *item )
{
static char buffer[50];
const struct node *value = item;
sprintf( buffer, "{ val: %d; next %p }", value->val, (void *) value->next );
return buffer;
}
const char *voidFmt( const void *item )
{
static char buffer[20];
sprintf( buffer, "%p", item );
return buffer;
}
int main( void )
{
int iArr[] = {1, 2, 3, 4, 5};
double dArr[] = {2.0, 4.0, 8.0, 16.0};
struct node nArr[] = { {1, NULL}, {2, NULL} };
void *arrs[] = { iArr, dArr, nArr };
nArr[0].next = &nArr[1];
print_array( iArr, sizeof iArr / sizeof *iArr, sizeof *iArr, intFmt );
putchar( '\n' );
print_array( dArr, sizeof dArr / sizeof *dArr, sizeof *dArr, dblFmt );
putchar( '\n' );
print_array( nArr, sizeof nArr / sizeof *nArr, sizeof *nArr, nodeFmt );
putchar( '\n' );
print_array( arrs, sizeof arrs / sizeof *arrs, sizeof *arrs, voidFmt );
putchar( '\n' );
return 0;
}
输出:
jbode:print_array john.bode$ ./print_array
{1, 2, 3, 4, 5}
{ 2.00, 4.00, 8.00, 16.00}
{{ val: 1; next 0x7ffeeafc5a70 }, { val: 2; next 0x0 }}
{0x7ffeeafc5a40, 0x7ffeeafc5a48, 0x7ffeeafc5a50}