2012-04-21 6 views
2

У меня есть два вопроса о char array.C++ - массив символов и нулевой символ

  1. из кода сильфона, так как arr является const, почему не компилятор дает мне ошибку, так как я переписывания?

    char arr[5]; // arr is a const pointer to (*)[5] array 
    cin>>arr; // 
    
  2. когда инициализируется массив символов, как это:

    char arr[5]={'h','i'}; 
    

    , если я сделал это:

    cout << arr << "something here \n"; 
    

    он будет печатать hisomething here. Я думал, что он должен распечатать

    hi something here 
    

    с 3мидесяти местами.

    Но если бы я сделал это:

    for(int i = 0; i < 5; i++){ 
        cout << arr[i]; 
    } 
    

    это будет распечатке 3 пробельные.

Второй случай, похоже, доказывает, что компилятор не добавляет никаких нулевых символов. Итак, как компилятор может игнорировать 3 пробела?

ответ

8
  1. Этот массив не const, поскольку нет классификатора const.
  2. Если вы не укажете оставшиеся значения в списке инициализаторов, они будут инициализированы до 0. 0 используется для прерывания строк C, а не как пробел.

Что касается вашего требования, то for(int i=0;i<5;i++){ cout << arr[i]; } печатных пробелов - как вы это проверили?

Для меня:

#include <iostream> 

int main(){ 
    char arr[5]={'h','i'}; 
    for(int i=0;i<5;i++){ std::cout << arr[i]; } 
    std::cout << "X" << std::endl; 
} 

печатает:

hiX 

и hexdumped:

$ ./t | hexdump -Cv 
00000000 68 69 00 00 00 58 0a        |hi...X.| 
00000007 

Есть '\0' символы напечатаны. Их дисплей, похоже, зависит от операционной системы. Но они не являются пробелами.

+0

, если они будут проиндексированы до 0, то почему во втором коде они были обработаны как пробелы? – AlexDan

+1

Почему, по-вашему, они воспринимаются как пробелы? Попробуйте перенаправить вывод в текстовый файл, а затем изучите его с помощью шестнадцатеричного редактора. –

+0

Я скопировал ваш код, Он напечатал hi X, а не hiX. – AlexDan

0

arr действует указатель const, что означает, что вы не можете установить указатель на другой адрес. Это не указатель на константу, поэтому вы можете изменить данные по адресу, на который указывает указатель.

Пример:

arr=&another_variable; //Illegal 
*arr='A';    //Legal 
+0

Да, я знаю это, но, к примеру, CIN >> обр; и я набрал «cpp». компилятор будет обрабатывать его так: 1) arr = "cpp" или как это 2) arr [0] = 'c', arr [1] = 'p', arr [2] = 'p'. – AlexDan

+0

Он будет обрабатывать это как: arr [0] = 'c', arr [1] = 'p', arr [2] = 'p' – user877329

3
  1. обр само по себе является "символ [5]" не "Const символ (*) [5]". И он неявно приводится к «char *» rvalue, когда вы пишете cin >> arr.Это не константа, потому что это даже не значение lvalue.

И «const char *» или «char const *» означает, что указанное значение lvalue не может быть изменено, в то время как «char * const» означает, что сам указатель lvalue не может быть изменен. Но это не имеет никакого отношения к вам.

  1. Во-первых, не было пробелов. И cin добавляет нулевой символ.

Массив это просто массив:

char a[5]; //a's type is char[5]; 

Но массив вряд ли может быть операндом. Только операторы, которых я помню, принимают тип массива sizeof и & (адрес) (С другой стороны, это означает, что иногда это должен быть массив. Или если вы напишете sizeof (a), он даст вам размер указателя.). Для других операций a преобразуется в char * rvalue. И да, даже когда вы пишете [0], a [1] и т. Д. A [0] эквивалентно * (a + 0), который работает с указателями, но не с массивами.

Если вы не можете назначить на что-то, это не всегда означает, что вещь «Уст»:

  1. Вы не можете присвоить константной переменной, конечно.
  2. Вы можете назначать только переменную (или aka lvalue), поэтому вы не можете присвоить значение rvalue (или значение aka). Таким образом, вы не можете написать 1 = 2, потому что 1 является rvalue не переменной, а не потому, что 1 является «const».
  3. Вы должны присвоить что-то переменной, соответствующей ее типу. Поэтому, если у вас есть const char * p и char * q, вы не можете написать q = p. Их типы не совпадают. И опять же, это не означает, что q является const, потому что это явно не так. Но вы можете написать p = q, потому что char * может быть неявно приведен к const char *. Но const char * должен быть явно передан char *.
+0

arr - указатель на const, поэтому вы не можете сделать это arr = "something" ,но вы говорите, что можете сделать это cin >> arr; например У меня есть cin >> arr; и я ввожу «cpp»; это будет заменено на arr [0] = 'c', arr [1] = 'p', arr [2] = 'p'; – AlexDan

+1

Вы не можете записать arr = "", потому что arr - массив, а не указатель. Даже если он неявно передан указателю, arr - это указатель rvalue, который не может быть назначен. Часть «cpp»: нет, вы пропустили arr [3] = '\ 0'; – BlueWanderer

+0

Об указателе const: если arr был const char *, вы бы не смогли написать char * x = arr, но на самом деле вы можете. – BlueWanderer

0
  1. первый не const. во-вторых, этот код небезопасен.
  2. U должен установить окончательный символ окончания '\ 0' в конце.

Нельзя использовать тип символа, попробуйте использовать строку вместо массива символов.