获得正确的char *地址

问题描述 投票:0回答:2

我试图理解C中char *操作的行为。这是我的驱动程序代码:

char *str1 = malloc(30);
char *str2 = "hello programmers.";
char *str4 = "and have a nice day.";
char *str5 = my_strcat(str2, str4);
my_strcpy(str1, str2);

和我对strcpy的实现:

void my_strcpy(char *dest, char *src){
  while ((*dest++ = *src++)); //dest value is at end of char*
}

1.离开my_strcpy时,根据我的理解,dest应该指向字符串的结尾(因为我们一直在增加它)。

现在让我们来看看我的strcat:

char* my_strcat(char *first, char *second){
  int l_first = strlen(first), l_second = strlen(second);
  char *tmp = malloc (l_first + l_second + 1);

  while ((*tmp++ = *first++));
  tmp--; // overwrite tmp's "\0"
  while ((*tmp++ = *second++)); // tmp value is end of char*
  tmp-=(l_first+l_second + 1); // rewinding pointer to string start.
  return tmp;
}

2.我必须手动“倒带”tmp才能在功能外正确打印。

简而言之,我的问题是为什么我会这样做?我不太确定如何描述我的问题,我希望它足够清楚。为什么我必须在第二个函数中“回放”我的指针,但不是第一个?而且,为什么我不必在第一个函数中“回放”src和dest?

我想到的可能的解释:

  1. char *通过值传递给函数,这就是为什么我不必通过调试器(在函数范围内检查和检出地址)来回绕src和dest - 证明错误。
  2. 在第一个函数中,我传递的是一个在范围外分配的指针,而在第二个函数中,tmp是在范围内分配的。

谢谢(我试图提供尽可能多的信息和尝试的解决方案,如一个好的问题应该是,抱歉,如果它出来太长)

c pointers
2个回答
2
投票

为什么我必须在第二个函数中“回放”我的指针,但不是第一个?而且,为什么我不必在第一个函数中“回放”src和dest

这是因为在C,一切都是价值传递。

  1. 当我们传递值时,我们将变量的副本传递给函数。
  2. 当我们传递引用时,我们将变量的别名传递给函数。它将指针的值(地址)复制到函数中。

因此,当你做(*dest++ = *src++)时,你没有增加实际变量,所以你的str2str4仍未受影响。

如果是char* my_strcat(char *first, char *second),则返回本地指针,该指针指向连接字符串中的最后一个字符,因此您需要回放。

如果你不想倒回指针,那么只需使用一个指向tmp开头的虚拟指针,然后使用return虚拟指针,如下所示。

char* my_strcat(char *first, char *second){
  int l_first = strlen(first), l_second = strlen(second);
  char *tmp = malloc (l_first + l_second + 1);

  char *result = temp;

  while ((*tmp++ = *first++));
  tmp--; // overwrite tmp's "\0"
  while ((*tmp++ = *second++)); // tmp value is end of char*

  return result;
}

0
投票

如果你想要更改dest指针,你需要传递对它的引用:

char* my_strcat(const char **dest, const char *source){
  size_t l_first = strlen(first), l_second = strlen(second);
  char *tmp = malloc (l_first + l_second + 1);
  char *result = temp;
  const char *tmpdest = *dest;

  if(tmp)
  {
      while ((*tmp++ = *tmpdest++));
      tmp--; // overwrite tmp's "\0"
      while ((*tmp++ = *second++)); // tmp value is end of char*
      *dest = result;
  }
  return result;
}
© www.soinside.com 2019 - 2024. All rights reserved.