2016-03-14 2 views
1
#include <iostream> 
using namespace std; 

int main() { 
    int * a[5]; 
    char * b[5]; 
    cout<<a[1]; // this works and prints address being held by second element in the array 
    cout<<b[1]; // this gives run time error . why ? 
    return 0; 
} 

Может ли кто-нибудь объяснить мне cout<<b[1] дает ошибку во время выполнения? Не должны ли оба массива int и char вести себя аналогично друг другу?разница между int * и char * in C++

+0

Вы имеете в виду, если он был инициализирован, там не будет ошибки? – g4ur4v

+0

Подумайте, что произойдет, если вы выполните 'const char * s =" Hello "; std :: cout << s; ", а затем подумайте, действительно ли вы будете ожидать, что' int * 'и' char *' будут вести себя одинаково. –

ответ

6

Потому что IOStreams предназначены для лечения char* специально.

char* обычно указывает на C-строку, поэтому IOStreams просто предположит, что они делают и разыгрывают их.

У вас нет.

2

C++ (наследующий его от C) специально предназначает указатели на символы. При попытке распечатать a[1] типа int* адрес печатается. Но когда вы пытаетесь напечатать b[1] типа char*, библиотека iostream, следуя остальной части языка, предполагает, что указатель указывает на первый символ строки с нулевым символом. Оба выходных оператора являются инициализированными, но в случае с char* сбой гораздо вероятнее, потому что указатель разыменован.

+0

Не существует «остальной части языка», которая безоговорочно обрабатывает char * как c-строки. – SergeyA

+0

@SergeyA Как насчет библиотеки C, других частей библиотеки C++ (например, std :: string), типа строковых литералов? –

+0

C библиотека не пытается отличить поведение по типу аргумента - по простой причине, что C вообще не перегружает функции. Что касается 'std :: string', он специально ожидает' char * 'в своих методах и обязывает его указывать на строку с нулевым завершением (если только размер не передан в конструкторе). Что касается типа строкового литерала, я не вижу, как это связано вообще. – SergeyA

2

Выходной поток, такой как cout, уделяет особое внимание char *, который он не дает другим указателям. Для указателей, отличных от char *, он просто распечатает значение указателя в виде шестнадцатеричного адреса. Но для char * он попытается распечатать строку C-style (т. Е. Нулевой конец символа), на которую ссылается char *. Поэтому он попытается разыменовать указатель на char, поскольку @AlexD указывает на комментарий к вашему сообщению.

+2

iostreams действительно обрабатывают некоторые другие типы указателей специально, 'signed char' и' unsigned char' получают аналогичную обработку. –

3

Как говорили другие, операторы вывода формата iostream рассматривают char*, чтобы указать на строку стиля C и попытаться получить доступ к этой строке.

Что еще не говорили до сих пор, заключается в том, что если вы заинтересованы в указателе, вам необходимо направить указатель на вопрос void*. Например:

Смежные вопросы