Разное поведение с разными типами массивов - PullRequest
0 голосов
/ 07 октября 2011

Я протестировал два различных варианта подобного кода, предположим, у меня есть массив символов

char x[]="snow comes in winter ";

затем следующий код

#include <iostream>
#include <string.h>
using namespace std;
int main(){

char x[]="snow comes in winter ";
int k=0;
int n=3;
cout<<x+n-k+1<<endl;
    system("PAUSE");
    return EXIT_SUCCESS;
}

отпечатков "comes in winter " при следовании

#include <iostream>
#include <string.h>
using namespace std;
int main(){

//char x[]="snow comes in winter ";
int a[]={12,3,2,4,5,6,7};
int k=0;
int n=3;
cout<<a+n-k+1<<endl;



return 0;
}

отпечатков 0xbffd293c если мы изменим это немного

#include <iostream>
#include <string.h>
using namespace std;
int main(){

//char x[]="snow comes in winter ";
int a[]={12,3,2,4,5,6,7};
int k=0;
int n=3;
cout<<*(a+n-k+1)<<endl;



return 0;
}

печать № 5. поэтому мой вопрос: почему мы можем так легко получить доступ к массиву символов? какова его главная причина? Мне очень любопытно, и, пожалуйста, кто-нибудь может мне объяснить?

Ответы [ 4 ]

9 голосов
/ 07 октября 2011

почему мы можем так легко получить доступ к массиву символов?

Поскольку существует соглашение, что строки C представлены char*, люди предполагают, что char* на самом деле строки.iostream s следуют за этим и выводят перегрузку для char* для печати строки, тогда как для int* (во втором примере) они печатают представление адреса.

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

char x[10];
std::cin >> x;
2 голосов
/ 07 октября 2011

Причины этого возвращаются к C.

В C, char* обычно используется для представления строки, заканчивающейся NUL (в отличие от указателя на отдельного пользователя char).Поэтому функции, принимающие char*, обычно обрабатывают аргумент как строку.В этом случае функция - operator<<, и она выводит аргумент в виде строки.

Ничего подобного нельзя сказать о int*, который является просто указателем на int.Здесь operator<< выводит значение указателя (то есть адрес).Только когда вы явно разыменовываете указатель, печатается указанное значение.

1 голос
/ 07 октября 2011

Для переменной foo типа Foo* выражение foo+n также имеет тип Foo* (при условии, что n является целочисленным типом).

Механизм по умолчанию std::ostreamдля печати указателя стоит распечатать указатель.Существует специальное переопределение для const char* указателей, которое предназначено для печати (предположительно) строки с нулевым символом в конце, на которую указывает этот указатель.

Нижняя строка: указатели, которые не являются char*, будут напечатаны как указатели.Указатели char* будут напечатаны в виде строки.

1 голос
/ 07 октября 2011

Оператор сдвига влево для cout перегружен для обработки указателей на символы. То есть, когда вы указываете ему указатель на символ, он разыменовывает указатель для вас, и поэтому вы получаете данные, на которые указывает. Это не происходит в случае int, потому что нет перегрузки, и поэтому вы должны разыменовать указатель самостоятельно.

...