为什么这个反转单词的 C++ 程序不起作用
Why is this c++ program to reverse a word not working
我是 c++ 的新手,写了这个程序来反转单词。我尝试的基本上是遍历一个数组,并将第一个字母与最后一个字母交换,第二个字母与倒数第二个字母交换等等。但是结果是一些有线字符 ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠Ω ⌠7p≈╗
。我不想变通,因为网上有很多例子。我只是想知道为什么我所做的不起作用。
#include <iostream>
using namespace std;
int main()
{
char word[10];
for (int i = 0; i < 10; i++)
{
word[i] = word[sizeof(word - i)];
}
cout << word << endl;
return 0;
}
它也给我这个警告warning C6001: using uninitialized memory 'word'
。但是我虽然通过 char word[10]
.
初始化了内存
在你的例子中 word
是 声明的 但不是 初始化的 。该警告意味着单词数组可以包含 un-initialized 个值。
char word[10];
要查看合理的字符而不是垃圾(未初始化的)值,请将值输入 word
或在代码中对其进行初始化。
为什么会出现这种行为?堆栈包含垃圾,直到程序将特定值放入堆栈上定义的变量中。
sizeof(word - 1)
将是 4 或 8。因为它是一个指针。
你需要的是 strlen(word)
.
此外,word
未初始化,请执行类似 char word[10] = "blabla"
的操作。
请注意,对于您所做的编辑,其中:
char word[5] = {'a', 'p', 'p', 'l', 'e'};
strlen
将不起作用,因为您需要一个字符为空,或 0
,才能知道字符串在哪里结束。
此外,您似乎是用 C++ 编写的,对于您拥有的这些东西 std::string
,您不需要 char 数组。然后你可以为长度调用 word.length()
,它可以动态设置字符串所需的大小并增长。
C/C++ 没有声明变量的自动初始化。你必须在引用之前用一个值填充每个数组,因为 C/C++ 使用指针。
问题是 sizeof(word - i)
实际上做了什么。
简短回答:returns 指针大小(4 或 8)。
更详细的回答:
word
具有类型 char[10]
和大小 10
- 当您执行
word + 1
时,编译器会将数组衰减为指向 char 的指针,以便能够执行此操作。所以结果类型是 char *
- 现在
sizeof(char *)
是 4 或 8,具体取决于您构建它的平台(32 位或 64 位)
- 所以
word[sizeof(word - i)]
总是指同一个单元格
还有第二个问题。在 C
中,文本字符串必须以 null 结尾以指示其大小。您的 word
包含末尾没有零字符的 apple
,因此在 apple
之后打印垃圾(它甚至可能使程序崩溃)。
此外,您的代码更像 C,在 C++ 中可以这样做:
int main()
{
std::string word{"apple"};
std::string reversed{word.rbegin(), word.rend()};
std::cout << word << '\n';
std::cout << reversed<< '\n';
return 0;
}
至少存在三个问题。
第一个是数组没有初始化,有一个不确定的值
char word[10];
第二个就是这个循环
for (int i = 0; i < 10; i++)
无论如何都不会颠倒数组。
即使在你像
这样更新数组之后
char word[5] = {'a', 'p', 'p', 'l', 'e'};
然而循环没有意义。
for (int i = 0; i < 10; i++)
还有这个表达式
sizeof(word - i)
不正确。由于指针运算,此表达式 word - i
具有类型 char *
。至少你是说
sizeof(word ) - i
相反,您可以编写如下内容
#include <iostream>
#include <utility>
#include <cstring>
//...
char word[] = "Hello World!";
for ( size_t i = 0, n = std::strlen( word ); i < n / 2; i++ )
{
std::swap( word[i], word[n - i - 1] );
}
std::cout << word << std::endl;
或者您可以编写一个单独的函数。给你。
#include <iostream>
#include <utility>
#include <cstring>
char * reverse( char *s )
{
for ( size_t i = 0, n = std::strlen( s ); i < n / 2; i++ )
{
std::swap( s[i], s[n - i - 1] );
}
return s;
}
int main()
{
char word[] = "Hello World!";
std::cout << word << '\n';
std::cout << reverse( word ) << '\n';
}
程序输出为
Hello World!
!dlroW olleH
我是 c++ 的新手,写了这个程序来反转单词。我尝试的基本上是遍历一个数组,并将第一个字母与最后一个字母交换,第二个字母与倒数第二个字母交换等等。但是结果是一些有线字符 ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠Ω ⌠7p≈╗
。我不想变通,因为网上有很多例子。我只是想知道为什么我所做的不起作用。
#include <iostream>
using namespace std;
int main()
{
char word[10];
for (int i = 0; i < 10; i++)
{
word[i] = word[sizeof(word - i)];
}
cout << word << endl;
return 0;
}
它也给我这个警告warning C6001: using uninitialized memory 'word'
。但是我虽然通过 char word[10]
.
在你的例子中 word
是 声明的 但不是 初始化的 。该警告意味着单词数组可以包含 un-initialized 个值。
char word[10];
要查看合理的字符而不是垃圾(未初始化的)值,请将值输入 word
或在代码中对其进行初始化。
为什么会出现这种行为?堆栈包含垃圾,直到程序将特定值放入堆栈上定义的变量中。
sizeof(word - 1)
将是 4 或 8。因为它是一个指针。
你需要的是 strlen(word)
.
此外,word
未初始化,请执行类似 char word[10] = "blabla"
的操作。
请注意,对于您所做的编辑,其中:
char word[5] = {'a', 'p', 'p', 'l', 'e'};
strlen
将不起作用,因为您需要一个字符为空,或 0
,才能知道字符串在哪里结束。
此外,您似乎是用 C++ 编写的,对于您拥有的这些东西 std::string
,您不需要 char 数组。然后你可以为长度调用 word.length()
,它可以动态设置字符串所需的大小并增长。
C/C++ 没有声明变量的自动初始化。你必须在引用之前用一个值填充每个数组,因为 C/C++ 使用指针。
问题是 sizeof(word - i)
实际上做了什么。
简短回答:returns 指针大小(4 或 8)。
更详细的回答:
word
具有类型char[10]
和大小10
- 当您执行
word + 1
时,编译器会将数组衰减为指向 char 的指针,以便能够执行此操作。所以结果类型是char *
- 现在
sizeof(char *)
是 4 或 8,具体取决于您构建它的平台(32 位或 64 位) - 所以
word[sizeof(word - i)]
总是指同一个单元格
还有第二个问题。在 C
中,文本字符串必须以 null 结尾以指示其大小。您的 word
包含末尾没有零字符的 apple
,因此在 apple
之后打印垃圾(它甚至可能使程序崩溃)。
此外,您的代码更像 C,在 C++ 中可以这样做:
int main()
{
std::string word{"apple"};
std::string reversed{word.rbegin(), word.rend()};
std::cout << word << '\n';
std::cout << reversed<< '\n';
return 0;
}
至少存在三个问题。
第一个是数组没有初始化,有一个不确定的值
char word[10];
第二个就是这个循环
for (int i = 0; i < 10; i++)
无论如何都不会颠倒数组。
即使在你像
这样更新数组之后char word[5] = {'a', 'p', 'p', 'l', 'e'};
然而循环没有意义。
for (int i = 0; i < 10; i++)
还有这个表达式
sizeof(word - i)
不正确。由于指针运算,此表达式 word - i
具有类型 char *
。至少你是说
sizeof(word ) - i
相反,您可以编写如下内容
#include <iostream>
#include <utility>
#include <cstring>
//...
char word[] = "Hello World!";
for ( size_t i = 0, n = std::strlen( word ); i < n / 2; i++ )
{
std::swap( word[i], word[n - i - 1] );
}
std::cout << word << std::endl;
或者您可以编写一个单独的函数。给你。
#include <iostream>
#include <utility>
#include <cstring>
char * reverse( char *s )
{
for ( size_t i = 0, n = std::strlen( s ); i < n / 2; i++ )
{
std::swap( s[i], s[n - i - 1] );
}
return s;
}
int main()
{
char word[] = "Hello World!";
std::cout << word << '\n';
std::cout << reverse( word ) << '\n';
}
程序输出为
Hello World!
!dlroW olleH