这个C代码段是做什么的

这个C代码段是做什么的,c,C,我试着用评论来解释,但不确定我的直觉是否正确 char *foo(char *s, int n) { char s2[10]; /* Create a empty string of size 10 */ char *c; /* Declare a pointer to a char */ strcpy(s2, s); /* Copy s into s2 */ c = s2; /* Set c equal to the

我试着用评论来解释,但不确定我的直觉是否正确

char *foo(char *s, int n)
{
    char s2[10];     /* Create a empty string of size 10 */
    char *c;          /* Declare a pointer to a char */
    strcpy(s2, s);  /* Copy s into s2 */
    c = s2;         /* Set c equal to the beginning of s2 */
    while(*c++);    /* Move c to the end of  s2 */
    *c = (n > 1) ? 's' : 0; /* If argument is greater than 1 change last char to a s, otherwise 0 */
    return s2;
}

该代码的目的是通过考虑参数n中通知的数字,将参数s中通知的单词附加在“s”之后,从而实现无声的多元化。换句话说,如果代码是正确的,如果n>1,那么它会在字符串的末尾追加一个s

但是,由于存在许多错误,所提供的代码将无法工作:

它假定s中通知的字符串长度不超过8个字符8++'s'+'\0',否则该函数可能会使进程崩溃或造成其他不期望的效果-您应该使用更安全的函数来执行字符串复制; 用于将指针移动到字符串末尾的循环会递增指针,直到为时已晚。它在\0 nul终止符之后停止,因为不管条件的结果如何,始终执行增量后运算符+。应该是*C C++; 它返回一个指向局部变量s2的无效指针,这可能会导致程序中出现多个问题,包括崩溃-您应该为结果动态分配内存,或者传递一个指针作为参数,指示字符串将存储在哪里,以及它可以占用多少字节; 它没有正确终止新字符串-不能保证该字符串将在附加的“s”之后包含另一个“\0”。
您提供的代码片段是一个非常糟糕的编码示例。它有很多问题:

对象s2被声明为一个有限大小为10的本地数组,并作为参数传递给strcpy,而不进行任何边界检查,这为可能的溢出打开了大门。 如果参数n的值大于1,则字符串的终止字符将替换为“s”,如果使用不当,可能会导致未定义的行为,例如传递给printf之类的函数

它返回局部变量的地址,如果取消引用,将导致未定义的行为


这基本上是正确的,但是*c=。。不是关于最后一个字符,而是关于空终止符。看起来它是用来给一个单词加复数的,给定数字,但它是非常破碎的。它会产生未定义的行为,这就是它所做的。s2是foo中的局部变量,您不能返回它,因为s2只有在foo返回之前才有效。此外,此代码没有考虑s2的大小,如果源字符串长度超过9个字符,则会出现缓冲区溢出,从而产生未定义的行为。这类似于以下情况之一,请告诉我此代码面试问题的所有错误。@user3386109同意可能的面试问题。至少有6个问题。关于取消引用是否会导致未定义行为的详细信息:返回指针本身是UB-即使调用代码不使用它。@chux确定吗?你能引用标准中的任何内容吗;a=foo。。;bar*a;我们同意a是UB。100%确认赋值a=foo也是无效值的UB赋值。剩下的:是福。。;就其本身而言。我有90%的信心是UB。如果还没有准备好的话,这是一个很好的问题。IAC,确定我们同意代码不应返回s2。@chux我几乎99.99%确定它不是UB。@chux为什么a=foo是UB?