你能从C中的空格*打印F值吗
好的,我正在尝试这样做,但它不起作用,因为我没有取消指针的引用。。。有没有一种方法可以在不为类型生成switch语句的情况下执行此操作你能从C中的空格*打印F值吗,c,pointers,void,C,Pointers,Void,好的,我正在尝试这样做,但它不起作用,因为我没有取消指针的引用。。。有没有一种方法可以在不为类型生成switch语句的情况下执行此操作 typedef struct { char *ascii_fmtstr; int len; int (*deserializer)(void *in, const char *ascii); int (*serializer)(const void *in, char *ascii); } FORMAT; const FORMA
typedef struct
{
char *ascii_fmtstr;
int len;
int (*deserializer)(void *in, const char *ascii);
int (*serializer)(const void *in, char *ascii);
} FORMAT;
const FORMAT formats[]=
{
{"%d\n", 2/2} //Int
,{"%s\n", STRSIZE/2} //String
,{"%.4f\n", 4/2} //Float
,{"%lld", 4/2} //Long-Long
,{"%s\n", STRSIZE/2} //Time
};
typedef struct {
int fmtindex;
void * vp;
} JUNK;
float f = 5.0f;
int i=1;
char foo[]="bar";
JUNK j[] = {
{2, &f}
,{0, &i}
,{1, foo}};
void dump(void)
{
int i;
for(i=0;i<2;i++)
printf(formats[j[i].fmtindex].ascii_fmtstr, j[i].vp);
}
typedef结构
{
字符*ascii_fmtstr;
内伦;
int(*反序列化器)(void*in,const char*ascii);
int(*序列化程序)(常量void*in,char*ascii);
}格式;
常量格式[]=
{
{“%d\n”,2/2}//Int
,{“%s\n”,STRSIZE/2}//字符串
,{“%.4f\n”,4/2}//浮点
,{“%lld”,4/2}//Long
,{“%s\n”,STRSIZE/2}//时间
};
类型定义结构{
int-fmtindex;
void*vp;
}垃圾;
浮球f=5.0f;
int i=1;
char foo[]=“bar”;
垃圾j[]={
{2,&f}
,{0,&i}
,{1,foo};
作废转储(作废)
{
int i;
对于(i=0;i您可以使用类似于%p
的内容打印指针本身,但是,如果要打印指针指向的内容,您需要告诉它它是什么:
printf ("%d", *((int*)myVoidPtr));
不允许仅仅因为编译器不知道它指向什么而取消引用void*
。这样想:任何指针都只指向一个内存位置。但是指针的类型决定了之后要解释/考虑的字节数。If它是char*
然后(取决于系统)如果是int*
4个字节,则解释1个字节。但是void*
具有无类型
。因此,由于这个简单的原因,您不能在C中取消引用void
指针。但是您可以使用printf()中的%p
格式说明符打印出它指向的地址
并将该void
指针作为参数传递
printf("The address pointed by void pointer is %p",void_ptr); //Correct
printf("The address pointed by void pointer is %p",(void*)int_ptr);//Correct
假设int_ptr
是一个整数指针,而void_ptr
是一个空指针
printf("Value at address pointed by void pointer is %d",*void_ptr);// Wrong
printf("Value at address pointed by void pointer is %d",*(void*)int_ptr);//Wrong
不清楚您的真正目标是什么。是的,有一些方法可以根据数据类型打印。基本上,这个想法是创建您自己的打印功能
但是仅仅提供指针是不够的。在任何情况下,您都需要提供指针及其类型
假设我们有一个函数myprint
:
myprint("%m %m %m %i", TYPE_INT, &i, TYPE_FLOAT, &f, TYPE_STRING, foo, 10);
可能是调用。myprint
是一个varargs函数,它需要重建格式字符串和参数,然后可以调用realprintf
如果只使用堆变量,则变量的类型可以通过一些技巧与数据一起存储(提示:检查malloc
如何存储块大小)。这将使附加参数成为超级参数
还有其他解决方案,但如果不了解您的真正目标和确切条件,就不可能提出好的建议。我认为printf
及其朋友(fprintf等)只能取消引用char*
,而这将被解释为c字符串
实际上,您可以自己编写这样的函数,因为您将告诉您的函数如何使用格式标志取消引用void*
您还可以将指向所需解引用函数的指针作为第三个值添加到格式中,该函数将以void*
作为参数,并返回值而不是指针。
因此,您需要为您在格式中使用的每种类型编写一个函数,并将每个函数正确地分配给每种格式。似乎您正在使用void*
作为廉价的union
。这是一个非常糟糕的主意。我想您会发现union
与enum
和switch
结合使用在C语言中,你可以在#ifdef开关中找到开关
。#else
,在#else
中找到无开关版本
#include <stdio.h>
struct object {
enum type {
d=0,
s=1,
f=2,
lld=3,
time=4
} type;
union instance {
int d;
char *s;
float f;
long long lld;
char *time;
} instance;
};
#ifdef SWITCH
void print_object(struct object *o) {
switch (o->type) {
case d: printf("%d", o->instance.d); break;
case s: printf("%s", o->instance.s); break;
case f: printf("%f", o->instance.f); break;
case lld: printf("%lld", o->instance.lld); break;
case time: printf("%s", o->instance.time); break;
};
}
#else
void print_d(struct object *o);
void print_s(struct object *o);
void print_f(struct object *o);
void print_lld(struct object *o);
void print_time(struct object *o);
void print_object(struct object *o) {
void (*print_functions[])(struct object *) = {
[d] = print_d,
[s] = print_s,
[f] = print_f,
[lld] = print_lld,
[time] = print_time
};
print_functions[o->type](o);
}
void print_d(struct object *o) { printf("%d", o->instance.d); }
void print_s(struct object *o) { printf("%s", o->instance.s); }
void print_f(struct object *o) { printf("%f", o->instance.f); }
void print_lld(struct object *o) { printf("%lld", o->instance.lld); }
void print_time(struct object *o) { printf("%s", o->instance.time); }
#endif
int main(void) {
struct object o = { .type = d, /* type: int */
.instance = { .d = 42 } /* value: 42 */ };
print_object(&o);
return 0;
}
#包括
结构对象{
枚举类型{
d=0,
s=1,
f=2,
lld=3,
时间=4
}类型;
联合实例{
int d;
char*s;
浮动f;
朗朗法学博士;
字符*时间;
}实例;
};
#ifdef开关
无效打印对象(结构对象*o){
开关(o->类型){
案例d:printf(“%d”,o->instance.d);break;
案例s:printf(“%s”,o->instance.s);break;
案例f:printf(“%f”,o->instance.f);break;
案例lld:printf(“%lld”,o->instance.lld);break;
案例时间:printf(“%s”,o->instance.time);中断;
};
}
#否则
无效打印(结构对象*o);
无效打印(结构对象*o);
无效打印(结构对象*o);
无效打印(结构对象*o);
无效打印时间(结构对象*o);
无效打印对象(结构对象*o){
void(*打印函数[])(结构对象*)={
[d] =打印,
[s] =打印,
[f] =打印,
[lld]=打印lld,
[时间]=打印时间
};
打印功能[o->type](o);
}
void print_d(结构对象*o){printf(“%d”,o->instance.d);}
void print_s(结构对象*o){printf(“%s”,o->instance.s);}
void print_f(结构对象*o){printf(“%f”,o->instance.f);}
void print_lld(struct object*o){printf(“%lld”,o->instance.lld);}
void print_time(结构对象*o){printf(“%s”,o->instance.time);}
#恩迪夫
内部主(空){
结构对象o={.type=d,/*type:int*/
.instance={.d=42}/*值:42*/};
打印对象(&o);
返回0;
}
这是正确的,但与OP的问题无关。因为他已经以该格式传递了类型信息,printf
拥有取消引用指针本身所需的所有信息(如果存在这种格式的话)。(事实上,这正是scanf
的工作方式,它的所有参数都是指针。)没有,但这是一个接口问题,不是他的方法的根本缺陷。我不认为printf和它的朋友可以从指针上解除引用,除了char*,这将被解释为sting。
我不理解你的意思。请详细说明@