从空格中得到一个浮点数* [关闭]

问题描述 投票:0回答:5

我正在尝试重新编程printf函数(大学项目)但%f导致我出现问题。我使用像这样的函数指针:

void (*fct[15])(void*) =
            {printfs, printfc, printfd, printfd, printfl, printfx, printfX,
             printfo, printfb, printfS, printfu, printfp, printff};

当使用右标志时,调用其中一个函数。典型的printfd将收到一个void *变量作为参数,并将这样做:

int nbr = (int)var;     //var is a void* type variable
my_put_nbr(var);        //handmade function wich displays numbers

事情是,出于一些奇怪的原因,当我为printff做同样的事情时,它没有用

float nbr = (float)var;

我收到了消息

error:指向预期浮点值的指针值float nbr =(float)var

我也尝试过这样的事情。如果我有

my_printf("%f", var);     //with var = 12.34

然后我调用printff()函数,该函数应该:

int nbr1 = (int)(var / 1);
int nbr2 = (int)(var % 1);

所以我通常有nbr1 = 12和nbr2 = 34然后我会在'。'之间显示两者。但它仍然无法正常工作,我得到的信息是:

错误:无效操作数到二进制*(有'void *'和'int')int nbr1 =(int)(var * 1)

我不在意,所以如果你有任何线索,请告诉我。此外,我不能使用像printf()之类的命令,这是本练习的规则,所以不要告诉我解决方案隐藏在这里。

c pointers variable-assignment
5个回答
2
投票

如果我正确理解你的问题,当你完全确定调用者部分时,在被调用的函数中,考虑到你在var中收到了参数,你可以做

  • 对于int printf("%d", *(int *)var);
  • 对于float / double printf("%f", *(double *)var);

等等。

请注意,变量函数不存在float类型,因为对于这些函数,由于默认参数提升,float类型被提升为double

详细说明,您不会将传入指针强制转换/分配给所需类型(无效[类型不匹配]和不需要的类型)。相反,您将void *参数强制转换为适当的调用者参数类型(基于您提到的标志),然后取消引用以获取该值。

这个比喻是基于C11,第6.3.2.3章中提到的属性

指向void的指针可以转换为指向任何对象类型的指针。指向任何对象类型的指针可以转换为指向void的指针并再次返回;结果应该等于原始指针。


1
投票

它被称为双关语。指针惩罚是UB。最安全的方法是将void指针中的数据memcpy到float变量。

float x; memcpy (&x, voidptr, sizeof(float));


1
投票

你没有正确地调用va_args。第二个参数必须是您期望从变量参数读取的数据类型,因为va_args需要正确的大小才能知道从哪里获取下一个参数。

虽然使用数组来存储所有可能的函数可能看起来很聪明,但实际上当你有一个更简单,更易读的方法时,你实际上会让事情变得更难。它也可能更具扩展性。

switch(format_char)
  {
case 'd':
  print_an_int(va_args(args,int));
break;
case 'f':
  print_an_float(va_args(args,float));
break;
  }

0
投票

尝试使用

int nbr = *((int *)var); 
float nbr = *((float *)var);

将void指针var转换为整数/浮点指针,然后获取存储在该内存地址中的值并将值存储到变量中

代替

int nbr =(int)var;

float nbr =(float)was;

将存储在var中的地址转换为int / float。在这里,您只是转换地址而不是存储在该地址中的值。


0
投票

而不是尝试从args提取参数并将结果传递给fct[i],而是直接将args传递给fct[i]并让他们进行提取。唯一需要注意的是,你不能通过价值来传递。

    fct[i](&args);

在每个printf *辅助函数中执行以下操作:

void printf_double (va_list *args) {      
   double val = va_arg(*args, double);
   // print it
}

注意float不是printf的有效类型,因为float在varargs调用中被提升为double

© www.soinside.com 2019 - 2024. All rights reserved.