strcat的指针版本

u5rb5r59  于 2023-04-05  发布在  其他
关注(0)|答案(5)|浏览(87)
#include <stdio.h>

void strpcat(char *s, char *t) {
    int i = 0;
    while (*s++ != '\0')
        i++;
    while ((*(s+i) = *t++) != '\0')
        i++;
}

int main(void) {
    char a[20] = "Hello";
    char b[] = "Bye";
    strpcat(a, b);
    printf("%s\n", a);

    return 0;
}

我想用指针重写strcat()函数,但当我运行程序时,没有任何变化。
a数组没有任何影响,我做错了什么?

8tntrjer

8tntrjer1#

有一个问题就是while循环

while (*s++ != '\0')
    i++;

如果*str等于'\0',那么指针s将递增。因此原始字符串不会改变。至少第二个字符串将被追加到数组中的源字符串之后。
另一个问题是在第二个while循环中使用变量i

while ((*(s+i) = *t++) != '\0')
     i++;

因为指针s已经在前一个while循环中递增。使用递增的变量i和递增的指针s,指针表达式s + i将具有不正确的地址。
变量i是冗余的。
可以通过以下方式声明和定义函数

char * strpcat( char *s, const char *t ) 
{
    char *p = s;

    while ( *p ) ++p; 

    while ( ( *p++ = *t++ ) != '\0' );

    return s;
}

并称之为

puts( strpcat( a, b ) );

注意,第二个参数应该用限定符const声明,因为第二个传递的字符串在函数中不会改变。

char * strpcat( char * restrict s, const char * restrict t );
tez616oj

tez616oj2#

你把事情搞复杂了

void strpcat(char* s, char* t) {
  while (*s++ != '\0')
  { // do nothing
  }

  s--;   // need to go back one char so s points to the `\0`.

  while ((*s++ = *t++) != '\0')  // remove the fancy and wrong stuff
  {
     // do nothing
  }
}
pobjuy32

pobjuy323#

2步方法:

  • 转到第一个字符串的NULL
  • 继续复制第二个字符串
void strpcat(char* s, char* t) {
  while (*s != '\0') { ++s; } // Go to the end
  while ((*s++ = *t++) != '\0') {} // Copy source to end of destination
}
kxe2p93d

kxe2p93d4#

如果应用KISS_principle

#include <string.h>

char* kisscat (char* restrict dst, const char* restrict src)
{
  char* end = dst + strlen(dst);
  strcpy(end, src);
  return dst;
}

现在,这不仅更具可读性,而且可能比手动滚动任何这些都要快。因为这些库调用可能会内联到一些非常有效的代码中。不像完全手工制作的函数。

mkshixfv

mkshixfv5#

您的实现将s递增到空指针之后,然后将t指向的字符串复制到s[i],以此类推。原始的空终止符不会被覆盖,因此printf("%s\n", a)仍然输出Hello,并且字符串复制到目标数组中太远,可能超出末尾,导致未定义的行为。
如果你想使用指针,不要同时使用索引和增量,如果没有指向空指针。
以下是修改后的版本:

#include <stdio.h>

char *strpcat(char *s, const char *t) {
    while (*s != '\0')
        s++;
    while ((*s = *t++) != '\0')
        s++;
    return s;   // return a pointer to the null terminator.
}

int main(void) {
    char a[20] = "Hello";

    printf("%s\n", a);

    char *p = strpcat(a, " world!");

    printf("%s\n", a);

    strcpy(p, " Bye.");

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

输出:

Hello
Hello world!
Hello world! Bye.

相关问题