有关char指针类型的C函数的问题,有人可以解释一下吗?

时间:2010-04-07 13:44:15

标签: c

有人可以帮我找到这个C函数中的错误吗?

    char* f(int i) {
            int i; 
            char buffer[20];
            switch ( i ) {
                    1: strcpy( buffer, "string1");
                    2: strcpy( buffer, "string2");
                    3: strcpy( buffer, "string3");
                    default: 
                    strcpy(buffer, "defaultstring");
            }
            return buffer;
    }

我认为这与类型转换有关。 我的编译器发出警告'int i的声明阴影参数'。

11 个答案:

答案 0 :(得分:8)

  char* f(int i) {
            int i; 

错误1:本地'i'参数隐藏函数参数

        char buffer[20];
        switch ( i ) {

错误2:您使用未初始化的本地“i”变量。

                1: strcpy( buffer, "string1");
                2: strcpy( buffer, "string2");
                3: strcpy( buffer, "string3");
                default: 
                strcpy(buffer, "defaultstring");
        }
        return buffer;

错误3:返回指向本地数组中元素的指针,该指针在函数返回时无效。 '缓冲'已超出范围。

答案 1 :(得分:6)

嗯,首先,你错过了switch语句中的'case'声明以及语句末尾的break。尝试将代码更改为:

    char* f(int i) {
            int i; 
            char buffer[20];
            switch ( i ) {
                    case 1: strcpy( buffer, "string1"); break;
                    case 2: strcpy( buffer, "string2"); break;
                    case 3: strcpy( buffer, "string3"); break;
                    default: 
                    strcpy(buffer, "defaultstring"); break;
            }
            return buffer;
    }

此外,您使用名为i的局部变量覆盖参数i。所以删除它:

    char* f(int i) {
            char buffer[20];
            switch ( i ) {
                    case 1: 
                         strcpy( buffer, "string1"); 
                         break;
                    case 2: 
                         strcpy( buffer, "string2"); 
                         break;
                    case 3: 
                         strcpy( buffer, "string3"); 
                         break;
                    default: 
                         strcpy(buffer, "defaultstring"); 
                         break;
            }
            return buffer;
    }

最后,您将返回一个char指针,该指针指向名为buffer的本地静态声明的字符数组。只要返回指向其第一个元素的指针(返回语句的作用),buffer就会超出范围。这意味着你最终得到一个指向不再存在的变量的指针。要解决此问题,您可以将指向缓冲区的指针传递给函数,如下所示:

    void f(char *buffer, int i) {
            switch ( i ) {
                    case 1: 
                         strcpy( buffer, "string1"); 
                         break;
                    case 2: 
                         strcpy( buffer, "string2"); 
                         break;
                    case 3: 
                         strcpy( buffer, "string3"); 
                         break;
                    default: 
                         strcpy(buffer, "defaultstring"); 
                         break;
            }
    }

最后一个版本应该可以使用,前提是确保buffer足够长以接受字符串。如果你真的想让它变得安全,那么也要考虑buffer的长度并根据你要复制的字符串的长度来检查它。

答案 2 :(得分:2)

这里应用了几个修复

    const char* f(int i) {
            switch ( i ) {
                    case 1: return "string1";
                    case 2: return "string2";
                    case 3: return "string3";
            }
            return "defaultstring";
    }

答案 3 :(得分:2)

有三大问题:

  1. int i被声明为函数参数和本地自动变量。删除第2行的int i;语句。
  2. case关键字必须继续使用switch语句中的每个值(例如case 1:而不是1:)。
  3. 您正在返回指向自动变量的指针。 char buffer[20];变量放在堆栈上,在函数返回后不再有效。相反,你应该在堆上分配内存并返回指向它的指针。
  4. 使用strdup代替strcpy更正了功能:

    char * f(int i) {
        switch (i) {
        case 1:
            return strdup("string1");
        case 2:
            return strdup("string2");  
        case 3:
            return strdup("string3");
        default:
            return strdup("defaultstring");
        }
    }
    

答案 4 :(得分:1)

您有一个参数i,并且您声明了一个局部变量i

声明一个与参数同名的局部变量,您无法再访问它们。您应该更改局部变量名称或参数名称。

答案 5 :(得分:1)

您声明了一个局部变量i,它会将i参数隐藏到该函数中。

答案 6 :(得分:1)

它会影响参数。我是函数参数,然后在函数内部声明。此外,您不能在堆栈上声明一个数组(char buffer [20])然后返回它。一旦函数退出,它(缓冲区)就会超出范围。

答案 7 :(得分:1)

问题正是它告诉你的。一开始就有:

char* f(int i) {
        int i; 

第二行定义了一个名为i的变量 - 它“隐藏”(隐藏)作为参数传递的i。当您对switch的值i执行时,您在局部变量的(未初始化的)值上执行此操作,而不是您收到的参数。

您还将buffer定义为f本地,因此返回它是一个问题 - 它在返回时不再存在。鉴于你所投入的是任何一个字符串文字,你最好直接返回字符串文字:

char const *f(int i) { 
    switch (i) { 
        case 1: return "string 1";
        case 2: return "string 2";
        case 3: return "string 3";
        default: return "default string";
    }
}

或者,您可以使用字符串数组:

char const *f(int i) { 
    char *strings[] = {"", "string 1", "string 2", "string 3"};
    if (i>0 && i<3) 
        return strings[i];
    return "default string";
}

答案 8 :(得分:1)

你正在返回一个局部变量 - 只能以泪水结束。

答案 9 :(得分:1)

这里有一些问题

  1. 您在第2行重新声明我。我已经是该功能的参数。您无需重新声明它。

  2. 您的switch语句语法不正确。正确的语法是这样的:case 1: /* do stuff */ break; case 2: /* do other stuff */ break;

  3. 您正在尝试返回指向堆栈分配缓冲区的指针。这将导致细微的问题,因为在函数返回后无法保证内存不被破坏。 strcpys的目的是什么?如果您只想返回这些字符串,只需返回这些字符串!

  4. 这就是我要做的事情:

    char* f(int i) {
            char buffer[20];
            switch ( i ) {
                    case 1: return "string1";
                    case 2: return "string2";
                    case 3: return "string3";
                    default: return "defaultstring";
            }
            return buffer;
    }
    

答案 10 :(得分:1)

  1. 如果你给我一个int,你就不需要本地的int。
  2. 的机构

    1: blabla;

  3. 你需要

    case 1: blabla; break;
    

    (对于1:2:和3:但不是默认值)

    3.我对此不确定(长时间不做C)但我认为在函数结束后缓冲区将为空。因此,您必须传递一个char数组(和大小)然后更改它。在那种情况下,你不需要做任何返回。