在 C++ 中用双指针打印字符串数组的每个字符
print each char of string array with double pointer in C++
程序应打印字符串数组的每个字符。
#include <iostream>
#include <string>
using namespace std;
int main()
{
const char* numbers[10]{"One", "Too", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Zero"};
/* This version did not work. Why?
for (const char** ptr = numbers; *ptr != nullptr; *ptr++) {
const char* pos = *ptr;
while (*pos != '[=10=]')
cout << *(pos++) << " ";
}
*/
for(unsigned int i = 0; i < sizeof(numbers) / sizeof(numbers[0]); ++i)
{
const char* pos = numbers[i];
while(*pos != '[=10=]')
printf("%c ", *(pos++));
printf("\n");
}
return 0;
}
我知道我的代码是 C++17 和 C 的混合体(在从 C 到 C++ 的过渡中,nullptr
、cout
是两个例子),但不确定第一个 for-loop
和
for (const char** ptr = numbers; *ptr != nullptr; *ptr++)
正确与否。它出什么问题了?
在这种情况下,是否有循环遍历字符串数组(char 数组,还不是字符串对象)的“最佳实践”,尤其是我想捕获的双指针?谢谢!
在你的第一个循环中,你在数组中寻找“nullptr”,但你没有把它放在那里。
您在阵列后读取未初始化的垃圾。
我建议使用std::vector或std::array
尝试这些编辑,看看会发生什么
const char* numbers[11]{"One", "Too", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Zero", NULL};
和
;i < sizeof(numbers)/sizeof(numbers[0])-1;
在第二个 for
循环中
基本上*ptr
指向相应字符串的开头。但是在最后一个之后,它就出界了。如果您真的必须与 nullptr
进行比较,以上方法就是这样做的。
编辑
是的,除了上述之外,ptr
应该递增,而不是 *ptr
。 *ptr
将遍历字符串而不是数组。
两件事 -
首先,在这个循环表达式中,您不需要在递增后取消引用 ptr
- *ptr++
.
for (const char** ptr = numbers; *ptr != nullptr; *ptr++)
^^
*ptr++
将被分组为 - *(ptr++)
,这意味着,(post) 增加 ptr
并取消引用 (post) 的结果增量。它应该只是 ptr++
,因为我们需要 ptr
指针在执行循环体后指向 numbers
数组中的下一个元素。
其次,如果你的循环条件正在检查 nullptr
那么循环正在迭代的数组应该有 nullptr
作为标记来指示数组的结尾,你需要增加数组的大小以及调整结束标记:
const char* numbers[11] {"One", "Too", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Zero", nullptr};
通过上述更改,以下循环应打印 numbers
数组字符串:
for (const char** ptr = numbers; *ptr != nullptr; ptr++) {
const char* pos = *ptr;
while (*pos != '[=12=]')
cout << *(pos++) << " ";
cout << "\n";
}
因为你在 numbers
数组中添加了一个新元素来标记数组的结尾,所以要小心,在第二个循环中,你正在做 sizeof(numbers)/sizeof(numbers[0])
来获取数组大小并且它将给出 11
并且第二个循环将最终访问 nullptr
这将是未定义的行为。从 sizeof
中减去 1
导致循环条件,或者在处理之前添加检查 pos != nullptr
。
程序应打印字符串数组的每个字符。
#include <iostream>
#include <string>
using namespace std;
int main()
{
const char* numbers[10]{"One", "Too", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Zero"};
/* This version did not work. Why?
for (const char** ptr = numbers; *ptr != nullptr; *ptr++) {
const char* pos = *ptr;
while (*pos != '[=10=]')
cout << *(pos++) << " ";
}
*/
for(unsigned int i = 0; i < sizeof(numbers) / sizeof(numbers[0]); ++i)
{
const char* pos = numbers[i];
while(*pos != '[=10=]')
printf("%c ", *(pos++));
printf("\n");
}
return 0;
}
我知道我的代码是 C++17 和 C 的混合体(在从 C 到 C++ 的过渡中,nullptr
、cout
是两个例子),但不确定第一个 for-loop
和
for (const char** ptr = numbers; *ptr != nullptr; *ptr++)
正确与否。它出什么问题了? 在这种情况下,是否有循环遍历字符串数组(char 数组,还不是字符串对象)的“最佳实践”,尤其是我想捕获的双指针?谢谢!
在你的第一个循环中,你在数组中寻找“nullptr”,但你没有把它放在那里。
您在阵列后读取未初始化的垃圾。
我建议使用std::vector或std::array
尝试这些编辑,看看会发生什么
const char* numbers[11]{"One", "Too", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Zero", NULL};
和
;i < sizeof(numbers)/sizeof(numbers[0])-1;
在第二个 for
循环中
基本上*ptr
指向相应字符串的开头。但是在最后一个之后,它就出界了。如果您真的必须与 nullptr
进行比较,以上方法就是这样做的。
编辑
是的,除了上述之外,ptr
应该递增,而不是 *ptr
。 *ptr
将遍历字符串而不是数组。
两件事 -
首先,在这个循环表达式中,您不需要在递增后取消引用 ptr
- *ptr++
.
for (const char** ptr = numbers; *ptr != nullptr; *ptr++)
^^
*ptr++
将被分组为 - *(ptr++)
,这意味着,(post) 增加 ptr
并取消引用 (post) 的结果增量。它应该只是 ptr++
,因为我们需要 ptr
指针在执行循环体后指向 numbers
数组中的下一个元素。
其次,如果你的循环条件正在检查 nullptr
那么循环正在迭代的数组应该有 nullptr
作为标记来指示数组的结尾,你需要增加数组的大小以及调整结束标记:
const char* numbers[11] {"One", "Too", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Zero", nullptr};
通过上述更改,以下循环应打印 numbers
数组字符串:
for (const char** ptr = numbers; *ptr != nullptr; ptr++) {
const char* pos = *ptr;
while (*pos != '[=12=]')
cout << *(pos++) << " ";
cout << "\n";
}
因为你在 numbers
数组中添加了一个新元素来标记数组的结尾,所以要小心,在第二个循环中,你正在做 sizeof(numbers)/sizeof(numbers[0])
来获取数组大小并且它将给出 11
并且第二个循环将最终访问 nullptr
这将是未定义的行为。从 sizeof
中减去 1
导致循环条件,或者在处理之前添加检查 pos != nullptr
。