【问题标题】:Why does this statement cause an error in one function but not in another in C?为什么这条语句在一个函数中导​​致错误,而在 C 中的另一个函数中却没有?
【发布时间】:2012-12-02 12:33:43
【问题描述】:

以下第一个程序中的声明 *p++ = *source++; 不会导致任何错误,但会导致错误 ISO C++ forbids cast to non-reference type used as lvalue 在第二个程序编译时。为什么会发生这种情况?

  • 第一个程序

    #include 
    
    char *my_strcpy(char *destination, char *source)
    {
        char *p = destination;
        while (*source != '\0')
        {
            *p++ = *source++;
        }
        *p = '\0'; 
        return destination;
    }
    
    int main()
    {
        char source[] = "A string to be used for demonstration purposes";
        char destination[80];   
        my_strcpy(destination, source);
        puts(destination);
        return 0;
    }
    
  • 第二个节目

    #include 
    
    char source[] = "A string to be used for demonstration purposes";
    char destination[80];
    
    int main()
    {
        char *p = destination;
        putchar('\n'); 
        while(*source != '\0') 
        {
            *p++ = *source++; 
        }
        *p = '\0';
        puts(destination);
        return 0;
    }
    

【问题讨论】:

  • 第二个,source是一个数组。所以source++ 是非法的。首先,传递给函数的是&source[0],所以函数有一个可以递增的指针。

标签: c compiler-errors iso


【解决方案1】:

这是因为您的第一个程序增加了一个指针,而在第二个程序中您将++ 运算符应用于数组。尽管数组通常表现得像指针,但它们不是指针。数组支持指针算术,但不支持将它们视为lvalue 的指针运算符(即尝试修改它们指向的位置)。

解决问题很简单 - 只需创建一个指向数组的指针,然后在循环中使用该指针,如下所示:

char *p = destination;
putchar('\n'); 
char *src = source;
while(*src != '\0') 
{
    *p++ = *src++; 
}
*p = '\0';
puts(destination);
return 0;

【讨论】:

    【解决方案2】:

    在第一个程序中,source 通过将其传递给my_strcpy 被转换为指向 char 的指针,因此您可以递增它。另一方面,在第二个程序中,source 仍然是一个数组,您不能递增数组。

    顺便说一句,我认为 C 库以非常短的方式实现 strcpy,如下所示:

    while((*dst++ = *src++));
    

    仅此而已

    【讨论】:

      【解决方案3】:

      你不能修改源,你已经创建了一个指向它的本地指针,就像你用 p 做目的地一样。 source 是一个静态定义的数组,所以你只能改变它的内容,不能改变它的地址。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-04
        • 1970-01-01
        • 2021-01-20
        • 1970-01-01
        • 2019-10-29
        • 1970-01-01
        • 1970-01-01
        • 2022-01-05
        相关资源
        最近更新 更多