将字符串理解为C ++中的指针

时间:2017-10-04 10:16:32

标签: c++ string pointers memory-management memory-address

我很难理解字符串作为指针。显然,字符串被理解为指向字符串的第一个地址的指针。所以使用“&” - 运算符我应该收到字符串第一个字符的地址。这是一个小例子:

#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”的每个字符的地址。当我使用演员long(&text[i])时,效果很好。但我不明白为什么。没有强制转换,显然“&amp;” - 运算符给出了要打印的字符串的起始地址。使用强制转换,它分别给出每个角色的地址。 也许某人可以向我解释一下 - 我真的很感激!

3 个答案:

答案 0 :(得分:4)

&text[i]相当于text + i,并使用指针算法将指针沿着char[]数组移动i个位置。效果是在第(i)个字符上启动cout,调用<<const char*的重载。这将输出从起始点到NUL终止符的所有字符。

text[i]但是char类型,调用<<char的重载。这会输出一个字符。

在C ++中,如果需要字符串,请改用std::string。如果cin >> text;text类型,您仍然可以写std::string!您的代码也不容易超出您的char缓冲区。

答案 1 :(得分:3)

要打印数组元素的地址,您可以这样做:

cout << " " << (void*)&text[i];

此:

cout << " " << &text[i];

相当于:

cout << " " << text + i;

表示您要求从索引i开始打印字符串。

答案 2 :(得分:3)

如果您有一个存储字符串的字符数组,例如

char text[] = "Hello";

然后将数组初始化为

char text[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

在本声明中

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', '\0' }

如果要写

std::cout << &text[2];

即如果表达式右侧的指针向右移动一个位置,则意味着您将处理字符串

{ 'l', 'l', 'o', '\0' }

等等。

这是operator <<重载像

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] );