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 пробела?

4 ответа

  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' печатные буквы Их отображение, кажется, зависит от операционной системы. Но они не являются пробелами.

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

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

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

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

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

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

Когда вы не можете присвоить что-либо, это не всегда означает, что это "const":

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

Вы не должны использовать тип char, попробуйте использовать строку вместо char.

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

Пример:

arr=&another_variable; //Illegal
*arr='A';              //Legal
Другие вопросы по тегам