【问题标题】:Issues reverting a char array with C++ via pointers通过指针使用 C++ 恢复 char 数组的问题
【发布时间】:2019-11-06 06:03:42
【问题描述】:

我很清楚,这方面的说明效率非常低/几乎已过时。实际上,我使用字符串开发了一个更简单的解决方案,但出于教育目的,我的大学决定要求我们通过使用指针和 char 数组而不是字符串来解决这个问题。

基本上,我需要传递一个预定义的 char 数组(一个特定的短语)并将其反转返回。

到目前为止,我的输出完全是胡言乱语(有些字符我什至​​无法在此处输入)所以我认为我一定是做错了什么,但我不明白为什么。

为了进行实验,我尝试手动将函数体末尾的 *ptr_cha 分配为类似于“Hello”的内容,但随后遇到了类型转换错误。如果我手动将 temp[0] 分配为“hello”,并跳过 for 循环并在最后简单地说 *ptr_cha[0] 等于 temp[0],我仍然得到胡言乱语。 如果我尝试在函数开始时输出 clone 的内容(在说它等于 ptr_cha[0] 之后),它会说内容是“d”,一个在原句中甚至不存在的字母。

这是我的全部代码:

#include <iostream>
#include <wchar.h>
#include <locale.h>
#include <array>

using namespace std;

void invertChar(char *ptr_cha[]);

int main()
{
   setlocale(LC_ALL, "");
   char sentence[] {"Pablito clavó un clavito que clavito clavó Pablito"};
   char *ptr_sentence[] {nullptr};
   *ptr_sentence = sentence;
   invertChar(ptr_sentence);
   cout << ptr_sentence[0];
};

void invertChar(char *ptr_cha[]) {
   char clone[] = {""};
   char temp[] =  {""};
   ptr_cha[0] = clone;
   int length = sizeof(clone)/sizeof(*clone);
   int j = length;
   for(int i = 0; i < length; i++) {
    temp[i] = clone[j];
    j--;
   };
   *ptr_cha[0] = temp[0];
};

如前所述,想法是将句子设置为其倒置形式并显示在输出中。

作为一个额外的附带问题:为什么在 c++ 中计算 char 数组的长度如此复杂/冗长?对于字符串,有一个简单的方法,在这里你必须完成整个“技巧”,将数组的大小除以其引用的大小。我什至看不到数组的存储大小除以其指针的存储大小如何返回数组的长度...

【问题讨论】:

  • 尝试长度/2 ...
  • 您可以使用strlen获取字符数组的长度
  • length - 1初始化j,因为0-indexing
  • 代码没有意义。不需要指针数组。在函数中,您用另一个覆盖指针。然后你计算数组大小,这没有任何意义,因为数组无论如何都是常数。然后您使用这些数组进行访问,它们不包含任何原始字符串,并且具有越界访问权限。你需要删除所有额外的东西,只需要一个数组,如果它就地,则进行交换,否则分配一个新数组并复制。
  • @SamiKuhmonen 指针数组在哪里?您是指函数参数中的 *ptr_cha[] 吗?如果我尝试只使用 *ptr_cha,它不会编译。这是它编译的唯一方法。交换必须在函数内部进行,并且必须通过指针进行,这是项目的要求。

标签: c++ arrays pointers char


【解决方案1】:

让我分解每个步骤中发生的事情。如果您使用的是 IDE,我强烈建议您调试程序并查看每个步骤中发生的情况。 (在您的代码中,我假设您想要反转“句子”而不是返回其反转版本的副本。)

wchar.harray 在这里没有用到,你可以删除这些行。 除此之外,您不应该将字符串传递给这样的函数。看this怎么做才好。

#include <iostream>
#include <wchar.h> // Not used.
#include <locale.h>
#include <array> // Not used.

using namespace std;

void invertChar(char *ptr_cha[]);

在这里,您应该只将sentence 传递给invertCharptr_sentence 是不必要且奇怪的(char* ptr_sentence 就足够了,因为现在它是一个包含指向chars 的指针的数组,并且您存储了sentence 在它的第一个插槽中)。

int main()
{
   setlocale(LC_ALL, "");
   char sentence[] {"Pablito clavó un clavito que clavito clavó Pablito"};
   char *ptr_sentence[] {nullptr};
   *ptr_sentence = sentence;
   invertChar(ptr_sentence);
   cout << ptr_sentence[0];
};

void invertChar(char *ptr_cha[]) {
   char clone[] = {""};
   char temp[] =  {""};

您将clone 分配给ptr_cha[0],现在ptr_cha[0] 引用clone 而不是sentence。此时您无法联系到sentence

   ptr_cha[0] = clone;

下面的第一行将更具描述性,如下所示:int length = sizeof(clone) / sizeof(clone[0])。这将clone 的大小除以其第一个元素的大小,基本上给你clone 的元素数量。除以元素大小很重要,因为如果clone 使用像char 这样的不是1 字节长的字符来存储字符会怎样。通过这个技巧,你可以得到任意数组的元素个数。

   int length = sizeof(clone)/sizeof(*clone);
   int j = length;
   for(int i = 0; i < length; i++) {

请记住,tempclone 都是空字符串,更准确地说,它们有 1 个元素,即表示字符串结尾的 \0 字符。 在循环的第一次运行中,您正在这样做:temp[0] = clone[1]clone 没有第二个元素(索引 1)。此时,您正在访问数组外的内容并将其分配给temp,在那里它被解释为char,从而导致一些“乱码”。

    temp[i] = clone[j];
    j--;
   };
   *ptr_cha[0] = temp[0];
};

总的来说,我建议您研究指针以及它们是如何工作的,因为它们可能有点棘手和令人困惑。


工作 C(++) 实现:

#include <iostream> // cout
#include <locale.h> // setlocale
#include <string.h> // strlen

void reverse(char* string)
{
    // Check whether our pointer really points to something or not.
    if (string == nullptr) return;

    // 'strlen' returns the size of a '\0' terminated character sequence (including the '\0').
    // We subtract 1 from the length because we don't want to swap the terminating
    // '\0' character with the first one.
    const int length = strlen(string) - 1;
    for (int i = 0, j = length; i < j; ++i, --j) {
        const char temp = string[i];
        string[i] = string[j];
        string[j] = temp;
    }
}

int main()
{
    setlocale(LC_ALL, "");
    char sentence[] = "Pablito clavó un clavito que clavito clavó Pablito";
    reverse(sentence);
    std::cout << sentence << '\n';
    return 0;
}

C++ 实现只是为了比较:

#include <algorithm> // reverse
#include <iostream> // cout
#include <locale> // locale, locale::global
#include <string> // string

void reverse(std::string& string)
{
    std::reverse(string.begin(), string.end());
}

int main()
{
    std::locale::global(std::locale(""));
    std::string sentence = "Pablito clavó un clavito que clavito clavó Pablito";
    reverse(sentence);
    std::cout << sentence << '\n';
    return 0;
}

【讨论】:

  • 非常感谢您的帮助。我目前正在阅读有关指针的更多信息,并且我已经看到了我所有的错误,您的代码真的很有帮助!
  • 还有一件事我忘了提,也许能解释一下(“-->”的意思是“指向”):sentence --> "Pablito..." ptr_sentence --> @ 987654358@ --> "Pablito..." 你看,你想要实现的是拥有指向"Pablito..."而不是sentence的东西,因为你想修改"Pablito..."而不是sentence的值(即基本上是"Pablito" 的第一个char内存地址)。如果你真的需要一个指向字符串 "Pablito..." 的指针,你可以这样做:char* ptr_sentence = sentence
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多