返回数组指针会产生"警告:从不兼容的指针类型返回"

时间:2014-12-30 20:11:48

标签: c compiler-warnings

我正在读C,我发现你不能从一个函数返回一个数组,但你可以从这个来源返回一个指针:Link

编译器发出此警告:

test.c:50: warning: return from incompatible pointer type

我给他们写了类似的代码,但我收到了

/*¯¯¯Input to Values¯¯¯*/
int * lineToXY(char line[]) {
    int i,j,k;
    double x,y;
    char xvalue[15];
    char yvalue[15];
    static double xypair[2];
    /*Split into two strings*/
    for (i=0;sizeof(line)>i;i++) {
        if (isValidChar(line[i])) {
            for (k=0;isValidChar(line[i+k]);k++) {
                xvalue[k] = line[i+k];
            }
            break;
        }
    }
    for (i=i+k;sizeof(line)>i;i++) {
        if (isValidChar(line[i])) {
            for (k=0;isValidChar(line[i+k]);k++) {
                yvalue[k] = line[i+k];
            }
            break;
        }
    }
    /*Parse each string as a double*/
    x = strtod(xvalue, NULL);
    y = strtod(yvalue, NULL);
    xypair[0] = x;
    xypair[1] = y;
    return xypair; /*<-------- this is the line which the compiler is referring to.*/
}

上面的代码来自:http://pastebin.com/jU48qypV

提前致谢,并希望你们都有一个可爱的圣诞节。

3 个答案:

答案 0 :(得分:1)

您返回的对象类型与函数的返回类型不匹配:

int * lineToXY(char line[]) { -----+   You've declared lineToXY to return a pointer to
  ...                              |   int, but you declare xypair as an array of
  static double xypair[2]; --------+   double; in the return statement, the expression
  ...                              |   xypair "decays" to an expression of type 
  return xypair; <-----------------+   double *, which is not int *, hence your warning
}

除非它是sizeof或一元&运算符的操作数,或者是用于在声明中初始化数组的字符串文字,表达式为类型“{元素数组T”将被转换(“衰减”)为“指向T的指针”类型的表达式,表达式的值将是第一个元素的地址阵列;这个表达式不是左值(IOW,它不能是赋值的目标)。

假设您将函数的返回类型更改为double *,此代码将起作用,但是......

通过声明xypair static,您将创建一个在函数的所有调用中都存在的单个实例;这通常不是不是一个好主意。该功能不再是重入,其中 为了你的目的可能会或可能不重要,但这并不是一个很好的习惯。

最好的方法是将目标数组传递给函数,而不是尝试返回它:

void lineToXY( char line[], size_t linesize, double xypair[] )
{
}
...
int main( void )
{
  char inputLine[SOME_SIZE];
  double pair[2];
  ...
  lineToXY( inputLine, sizeof inputList, pair );
  ...
}

答案 1 :(得分:0)

在C

函数无法返回数组,您应该返回int *

你应该有像

这样的东西
int *p= malloc(sizeof(int) * 2);

p[0] = 5;
p[1] = 10;

return p;

在您的功能lineToXY()

否则,您可以拥有一个如图所示的静态数组,并返回该数组的基址。

static int r[2];

r[0] = 5;
r[1] = 10;

return r;

您的数组属于double类型,并且您正在尝试返回int *请修复此问题,同时返回double *或拥有int数组

答案 2 :(得分:-1)

无论如何,你通常不应该这样做。但实际问题是函数返回int *并且您应该返回double *int *double *是不兼容的指针。

你可以通过我能想到的几种方式来做到这一点,并且你的lineToXY函数会做很多不必要的工作,只需尝试第一个选项

void lineToXY(char line[], double xypair[2])
{
    char *token;
    char *saveptr;
    char *endptr;


    token = strtok_r(line, ",", &saveptr);
    if (token == NULL)
        return;
    xypair[0] = strtod(token, &endptr);

    token = strtok_r(NULL, ",", &saveptr);
    if (token == NULL)
        return;
    xypair[1] = strtod(token, &endptr);
}

int main()
{
    double xypair[2];
    char line[] = "123456789,9215487";

    lineToXY(line, xypair);
    printf("%f, %f\n", xypair[0], xypair[1]);

    return 0;
}

您可以使用结构

struct XYPair
{
    double x;
    double y;
};

struct XYPair lineToXY(char *line)
{
    char *token;
    char *saveptr;
    char *endptr;
    struct XYPair xypair = {0.0, 0.0};

    token = strtok_r(line, ",", &saveptr);
    if (token == NULL)
        return xypair;
    xypair.x = strtod(token, &endptr);

    token = strtok_r(NULL, ",", &saveptr);
    if (token == NULL)
        return xypair;
    xypair.y = strtod(token, &endptr);

    return xypair;
}

int main()
{
    struct XYPair xypair;
    char line[] = "123456789,9215487";

    xypair = lineToXY(line);
    printf("%f, %f\n", xypair.x, xypair.y);

    return 0;
}

或者您可以使用动态内存分配

double *lineToXY(char line[])
{
    char *token;
    char *saveptr;
    char *endptr;
    double *xypair;

    xypair = malloc(2 * sizeof(double));
    if (xypair == NULL)
        return NULL;
    xypair[0] = 0.0;
    xypair[1] = 0.0;

    token = strtok_r(line, ",", &saveptr);
    if (token == NULL)
        return xypair;
    xypair[0] = strtod(token, &endptr);

    token = strtok_r(NULL, ",", &saveptr);
    if (token == NULL)
        return xypair;
    xypair[1] = strtod(token, &endptr);

    return xypair;
}

int main()
{
    double *xypair;
    char line[] = "123456789,9215487";

    xypair = lineToXY(line);
    if (xypair == NULL)
        return -1;
    printf("%f, %f\n", xypair[0], xypair[1]);
    free(xypair); // you have to call free when you no longer need the data

    return 0;
}

您需要知道的一件事是strtok_r需要传递给它的可变字符串,因此如果您传递字符串文字,则需要使用strdupmalloc来复制它。 strcpy或您可以想到的任何其他方式。

代码中的sizeof运算符给出了指针的大小,这不是字符串的长度,你可以像使用代码那样执行它,但是你需要重新考虑算法,因为它有一些的问题。

在上面提出的三个解决方案中,struct是我认为最好的解决方案。