将字符串理解为 C++ 中的指针
Understanding strings as pointers in C++
我很难将字符串理解为指针。显然,字符串被理解为指向字符串首地址的指针。所以使用“&”运算符我应该接收到字符串第一个字符的地址。这是一个小例子:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(){
char text[101];
int length;
cout << "Enter a word: ";
cin >> text;
length = strlen(text);
for (int i = 0; i <= length; i++) {
cout << " " << &text[i];
}
return 0;
}
当输入 "Hello" 等单词时,输出为:"Hello ello llo lo o"。相反,我希望收到 "Hello" 每个字符的地址。当我使用 cast long(&text[i])
时,效果很好。但我不明白为什么。如果没有转换,显然“&”运算符给出了要打印的字符串的起始地址。它使用强制转换分别给出每个字符的地址。
也许某人。可以向我解释一下 - 我真的很感激!
&text[i]
等同于 text + i
并且使用 指针算法将指针沿 char[]
数组移动 i
个位置.效果是在第 (i) 个字符上开始 cout
,将 <<
重载到 const char*
调用。输出从起点到 NUL 终止符的所有字符。
然而 text[i]
是 char
类型,<<
到 char
的重载被调用。输出单个字符。
在 C++ 中,如果您需要字符串,请改用 std::string
。如果 text
是 std::string
类型,您仍然可以写 cin >> text;
!然后,您的代码也不容易溢出 char
缓冲区。
要打印数组元素的地址,您可以这样做:
cout << " " << (void*)&text[i];
这个:
cout << " " << &text[i];
相当于:
cout << " " << text + i;
这意味着您要求打印字符串,从索引 i
开始。
例如,如果您有一个存储字符串的字符数组
char text[] = "Hello";
然后数组像
一样被初始化
char text[] = { 'H', 'e', 'l', 'l', 'o', '[=11=]' };
在此声明中
std::cout << text;
使用 operator <<
重载类型 const char *
并且数组 text
被隐式转换为指向其第一个元素的指针。
你可以改写
std::cout << &text[0];
因为在这两个语句中,表达式 text
和 &text[0]
的类型都是 char *
.
为类型 const char *
重载的运算符从指针的地址开始输出字符,直到遇到零字符。
所以如果不是语句
std::cout << &text[0];
你会写
std::cout << &text[1];
那么唯一改变的就是字符串的起始地址,仅此而已。那实际上你正在输出表示为
的字符串
{ 'e', 'l', 'l', 'o', '[=16=]' }
如果要写
std::cout << &text[2];
也就是说,如果表达式右侧的指针向右移动一位,则表示您将处理字符串
{ 'l', 'l', 'o', '[=18=]' }
等等。
也就是operator <<
重载like
template<class traits>
basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&,
const char*);
仅将第二个参数指向的实体输出为字符串。
如果你想输出指针本身的值而不是指针指向的字符串,你应该使用另一个重载的 operator <<
声明为
basic_ostream<charT, traits>& operator<<(const void* p);
Tp 调用它你应该写例如
std::cout << ( void * )text;
或
std::cout << ( void * )&text[i];
其中 i
是一些索引。
您可以使用 C++ 转换而不是 C 转换,例如
std::cout << static_cast<void *>( &text[i] );
我很难将字符串理解为指针。显然,字符串被理解为指向字符串首地址的指针。所以使用“&”运算符我应该接收到字符串第一个字符的地址。这是一个小例子:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(){
char text[101];
int length;
cout << "Enter a word: ";
cin >> text;
length = strlen(text);
for (int i = 0; i <= length; i++) {
cout << " " << &text[i];
}
return 0;
}
当输入 "Hello" 等单词时,输出为:"Hello ello llo lo o"。相反,我希望收到 "Hello" 每个字符的地址。当我使用 cast long(&text[i])
时,效果很好。但我不明白为什么。如果没有转换,显然“&”运算符给出了要打印的字符串的起始地址。它使用强制转换分别给出每个字符的地址。
也许某人。可以向我解释一下 - 我真的很感激!
&text[i]
等同于 text + i
并且使用 指针算法将指针沿 char[]
数组移动 i
个位置.效果是在第 (i) 个字符上开始 cout
,将 <<
重载到 const char*
调用。输出从起点到 NUL 终止符的所有字符。
text[i]
是 char
类型,<<
到 char
的重载被调用。输出单个字符。
在 C++ 中,如果您需要字符串,请改用 std::string
。如果 text
是 std::string
类型,您仍然可以写 cin >> text;
!然后,您的代码也不容易溢出 char
缓冲区。
要打印数组元素的地址,您可以这样做:
cout << " " << (void*)&text[i];
这个:
cout << " " << &text[i];
相当于:
cout << " " << text + i;
这意味着您要求打印字符串,从索引 i
开始。
例如,如果您有一个存储字符串的字符数组
char text[] = "Hello";
然后数组像
一样被初始化char text[] = { 'H', 'e', 'l', 'l', 'o', '[=11=]' };
在此声明中
std::cout << text;
使用 operator <<
重载类型 const char *
并且数组 text
被隐式转换为指向其第一个元素的指针。
你可以改写
std::cout << &text[0];
因为在这两个语句中,表达式 text
和 &text[0]
的类型都是 char *
.
为类型 const char *
重载的运算符从指针的地址开始输出字符,直到遇到零字符。
所以如果不是语句
std::cout << &text[0];
你会写
std::cout << &text[1];
那么唯一改变的就是字符串的起始地址,仅此而已。那实际上你正在输出表示为
的字符串{ 'e', 'l', 'l', 'o', '[=16=]' }
如果要写
std::cout << &text[2];
也就是说,如果表达式右侧的指针向右移动一位,则表示您将处理字符串
{ 'l', 'l', 'o', '[=18=]' }
等等。
也就是operator <<
重载like
template<class traits>
basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&,
const char*);
仅将第二个参数指向的实体输出为字符串。
如果你想输出指针本身的值而不是指针指向的字符串,你应该使用另一个重载的 operator <<
声明为
basic_ostream<charT, traits>& operator<<(const void* p);
Tp 调用它你应该写例如
std::cout << ( void * )text;
或
std::cout << ( void * )&text[i];
其中 i
是一些索引。
您可以使用 C++ 转换而不是 C 转换,例如
std::cout << static_cast<void *>( &text[i] );