printf with arguments函数返回指向char的指针

时间:2016-11-25 10:49:39

标签: c printf

您好我尝试设置像

这样的代码
#include <stdio.h>

struct _data;
typedef struct _data data;
typedef struct _data {
    double x;
    double y;
} data;

const char* data_tostring(data* a) {
    static char buffer[255];
    sprintf(buffer, "%f %f", a->x, a->y);
    return buffer;
}

int main(){
    data a;
    data b;
    a.x = 0;
    a.y = 0;
    b.x = 1;
    b.y = 1;
    printf("%s %s \n", data_tostring(&a), data_tostring(&b));
    return 0;
}

我预计输出为0 0 1 1,但实际上我得到0 0 0 0.我是否在static关键字和data_tostring()中返回值时出错?

感谢您的帮助。

2 个答案:

答案 0 :(得分:5)

由于bufferstatic,因此对data_tostring(...)的两次调用都写入同一缓冲区。此外,函数参数的评估顺序未指定,因此无法保证在data_tostring(&a)之前评估data_tostring(&b)

解决此问题的一种可能方法是将buffer作为参数传递给data_tostring

void data_tostring(char* buffer, data* a) {
    sprintf(buffer, "%f %f", a->x, a->y);
}

然后在main中使用多个缓冲区:

int main()
{
    data a;
    data b;
    char a_buf[255];
    char b_buf[255];

    a.x = 0;
    a.y = 0;
    b.x = 1;
    b.y = 1;

    // Fill buffers
    data_tostring(a_buf, &a);
    data_tostring(b_buf, &b);

    printf("%s %s \n", a_buf, b_buf);
    return 0;
}

wandbox example

如果您真的想使用static buffer,可以拨打printf两次:

int main()
{
    data a;
    data b;
    a.x = 0;
    a.y = 0;
    b.x = 1;
    b.y = 1;
    printf("%s", data_tostring(&a));
    printf(" %s \n", data_tostring(&b));
    return 0;
}

wandbox example

答案 1 :(得分:1)

  • 问题是因为在C语言中,函数中的参数是从right to left 计算的。
  • 因此,首先评估data_tostring(&b),指针指向缓冲区char数组。
  • 接下来,评估data_tostring(&a),这次,sprintf(buffer, "%f %f", a->x, a->y);已覆盖已存在的字符值。
  • 因此,在两个参数评估之后,两个函数评估指向缓冲区char数组,其值为struct a。这就是你得到0 0 0 0的原因。

替代解决方案:

  

使用两个printf()语句并单独打印字符串或为每个结构使用两个char缓冲区(不推荐)。

参考:Compilers and argument order of evaluation in C++

希望这有帮助。