Форум программистов, компьютерный форум CyberForum.ru

Семантика массивов char. - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.67
ligorlwow
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 19
14.03.2012, 13:14     Семантика массивов char. #1
Добрый день. Мы все знаем, что в C и С++ создав два массива подрят.. запросив элемент привышающий размерность первого мы зайдем во второй. Так вот столкнулся со след проблемой в массивах типа char.
Написав следующее :
C++
1
2
3
4
char a[2];
a[0]='2';
a[1]='4';
cout<<a; // я получил 24 , что и мною ожидалось.
Написав следующее :
C++
1
2
3
4
5
char a[2];
int b=(int)'0';
a[0]='2';
a[1]='4';
cout<<a; // я получаю 240, что я лично не ожидал..
За место int b=(int)'0'; можно инициализовать любую переменную и мы получим мусор, я взял '0' для наглядности проблемы.. В последующим изменение переменной char a[2] она ведет себя как состоящая из 3 элементов. Плз, прошу помочь разобратся в сути проблемы. Только не пишити "Используй strcat и т.д...." мне надо.. понять, почему cout выводит массив из 3 , а не из 2 элементов.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Van111
кодер с++
208 / 187 / 4
Регистрация: 03.08.2011
Сообщений: 2,585
Записей в блоге: 12
14.03.2012, 15:39     Семантика массивов char. #2
Цитата Сообщение от ligorlwow Посмотреть сообщение
"Используй strcat и т.д...." мне надо.. понять, почему cout выводит массив из 3 , а не из 2 элементов.
cout не рассчитан на вывод массива !!!!

Добавлено через 53 секунды
Цитата Сообщение от ligorlwow Посмотреть сообщение
char a[2];
a[0]='2';
a[1]='4';
cout<<a; // я получил 24 , что и мною ожидалось.
вывилось число размером в четыре байта(третий и четвёртый оказались наверно нулями )
напиши cout <<(char)a[0];

Добавлено через 5 минут
Цитата Сообщение от ligorlwow Посмотреть сообщение
почему cout выводит массив из 3 , а не из 2 элементов
потому что a это указатель состоящий из четырёх байт (на xp, процессор intel)

Добавлено через 4 минуты
вот дамп памяти
dd a 0x..... //адресс
db 2 //a[0]
db 4//a[1]
dd 0//int b возможно вот так расположились элементы
cout получает адресс и выводит число по этому адрессу ,а за размер вывода берёт размер аргумента который получил

Добавлено через 1 минуту
у меня они располагаются чуть по другому и в результате выводится
24# (четыре символа)
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
14.03.2012, 15:40     Семантика массивов char. #3
Имя массива без индекса это константный указатель на первый элемент, при написании cout << a; вы выводите содержимое указателя, то есть адрес на первый элемент, а не массив.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,307
14.03.2012, 15:41     Семантика массивов char. #4
Цитата Сообщение от ligorlwow Посмотреть сообщение
Мы все знаем, что в C и С++ создав два массива подрят.. запросив элемент привышающий размерность первого мы зайдем во второй.
Мы все знаем, что это неверно. Расположение различных переменных (а два массива - это две разных переменных) в памяти не специфицируется. Достоверно можно утверждать только одно: запросив элемент, превышающий размерность первого массива, мы попадем "куда-то".... а вот что "там" окажется - это уж зависит от фазы Луны....
Van111
кодер с++
208 / 187 / 4
Регистрация: 03.08.2011
Сообщений: 2,585
Записей в блоге: 12
14.03.2012, 15:42     Семантика массивов char. #5
Цитата Сообщение от Toshkarik Посмотреть сообщение
Имя массива без индекса это константный указатель на первый элемент, при написании cout << a; вы выводите содержимое указателя, то есть адрес на первый элемент, а не массив.
а как объяснить результат этого вывода?


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <stdlib.h>
using namespace std;
 
 
int main()
{
int x[10];
char a[2];
a[0]='2';
a[1]='4';
int b=48;
cout<<a;  
 
 system("pause");
 return 0;   
}
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
14.03.2012, 16:02     Семантика массивов char. #6
Van111, возможно что это зависит от компилятора, я пока еще не такой гуру Знаю не все, но могу предположить, что так как char a[] это строка, возможно cout перегружен на вывод строк, но в ней нет ноль-символа. Поэтому затрудняюсь.
co6ak
Кошковед
 Аватар для co6ak
402 / 495 / 29
Регистрация: 12.04.2010
Сообщений: 1,392
14.03.2012, 16:16     Семантика массивов char. #7
Вопрос про Swich
тоже забавка
Abendstern
3 / 3 / 0
Регистрация: 06.11.2011
Сообщений: 38
14.03.2012, 16:26     Семантика массивов char. #8
Вообще cout умеет выводить строки завешённые нуль-символом, разве не так?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
int main()
{
    char a[3];
    a[0] = '2';
    a[1] = '4';
    a[2] = '\0';
    
    int b=(int)'0';
    
    std::cout << a << '\n';
 
    return 0;
}
ligorlwow
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 19
14.03.2012, 19:45  [ТС]     Семантика массивов char. #9
Всем спасибо за ответы.. Насчет 4 байтов.. у меня не так(( Просто та же самая sizeof(a) в обоих случаях выводит 2. String да.. занимает 4 байта. Насчет того, что а - указатель на первый элемент, но вродь cout умеет выводить именно массив(чаровский). Система : Win 7 64 , проц Phenom 955.
Cool-T
20 / 13 / 1
Регистрация: 17.12.2010
Сообщений: 34
14.03.2012, 19:51     Семантика массивов char. #10
Цитата Сообщение от ligorlwow Посмотреть сообщение
Насчет того, что а - указатель на первый элемент, но вродь cout умеет выводить именно массив(чаровский).
Так он и выводит, пока не встретит 0x00

Например код
C++
1
2
3
4
5
char a[2];
    int b=(int)'0';
    a[0]='2';
    a[1]='4';
    cout<<a;
Выводит у меня
24╠╠╠╠╠╠`°8 в общем всю кашу ^^
ligorlwow
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 19
14.03.2012, 20:14  [ТС]     Семантика массивов char. #11
Ну тогда логичо, что компиль должен сам этим заниматся или нет?(всмысле вставлять 0x30) Просто тогда какой смысл указывать размерность..? Указав сейчас char a[0]; и последний элемент a[2]='\0';
То я получил 24....
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
14.03.2012, 20:52     Семантика массивов char. #12
Если строка объявляется так
C++
1
char a[] = "hello";
то символ '\0' вставится автоматически и размер будет не 5 по количеству букв а 6. Если же написать вот так
C++
1
char a[ 5 ] = "hello";
то естественно не будет ограничивающего символа. И проверка уже ложится на программиста.
ligorlwow
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 19
14.03.2012, 21:01  [ТС]     Семантика массивов char. #13
Спсибо за ответ...) Придется самому задавать..)) Все тему можно закрывать..)
Abendstern
3 / 3 / 0
Регистрация: 06.11.2011
Сообщений: 38
15.03.2012, 11:23     Семантика массивов char. #14
Цитата Сообщение от Toshkarik Посмотреть сообщение
Если же написать вот так
C++
1
char a[ 5 ] = "hello";
то естественно не будет ограничивающего символа. И проверка уже ложится на программиста.
Тем более, что это это приведёт к ошибке компиляции
Van111
кодер с++
208 / 187 / 4
Регистрация: 03.08.2011
Сообщений: 2,585
Записей в блоге: 12
15.03.2012, 17:44     Семантика массивов char. #15
Цитата Сообщение от Abendstern Посмотреть сообщение
Тем более, что это это приведёт к ошибке компиляции
если хотим без нулего символа то это делается так
C++
1
2
char a[5];
memcpy(a,"hello",5);
Добавлено через 2 минуты
отладчиком проверял - ноль не добавляется но слово почему то cout`ом выводится нормально
Abendstern
3 / 3 / 0
Регистрация: 06.11.2011
Сообщений: 38
15.03.2012, 18:17     Семантика массивов char. #16
Van111
Да, у меня также выводится. Может от компилятора зависит, но у меня на gcc так.

И даже если попробовать как в изначальном примере. Если добавить ещё одну переменную, допустим:

C++
1
2
3
char b = 'x'; 
char a[5];
memcpy(a,"hello",5);
То выведется hellox, как будто бы дальше есть нулевой символ. Но откуда бы ему там взяться...если там должен быть всякий мусор.

Добавлено через 14 минут
Вот ещё простой пример:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
{
    char a[3];
    
    a[0] = 'h';
    a[1] = 'e';
    a[2] = 'y';
    
    std::cout << "a = " << a << "\n";
    
    std::cout << "characters = ";
    for(int i = 0; i < 10; ++i)
        std::cout << a[i];
        
    return 0;
}
результат
a = hey
characters = hey♥ Р¤


Каким образом cout догадывается, когда ему закончить ввод? За последним элементом массива как видно, мусор. Почему он не выводится в этом случае? Разве cout "знает" о размере массива? Вот объясните мне кто-нибудь, я честно не понимаю.
Cool-T
20 / 13 / 1
Регистрация: 17.12.2010
Сообщений: 34
15.03.2012, 21:06     Семантика массивов char. #17
Цитата Сообщение от Abendstern Посмотреть сообщение
Каким образом cout догадывается, когда ему закончить ввод?
Может в gcc уже некоторые фичи из c++11 реализованы? Например "массив знает свой размер".

Потому что у меня всегда выводит мусор до первого \0 (Visual Studio 10 Express).
Запускал несколько раз подряд твой простой пример, почему-то в 30-50% случаев нулевой символ сразу после массива :]
Van111
кодер с++
208 / 187 / 4
Регистрация: 03.08.2011
Сообщений: 2,585
Записей в блоге: 12
16.03.2012, 17:39     Семантика массивов char. #18
Цитата Сообщение от Abendstern Посмотреть сообщение
Каким образом cout догадывается, когда ему закончить ввод? За последним элементом массива как видно, мусор. Почему он не выводится в этом случае? Разве cout "знает" о размере массива? Вот объясните мне кто-нибудь, я честно не понимаю.
если запустить под шеснадцетиричным редакторомто, то по умлчанию сегмент данных обычно заполняется нулями . Из этого следует что если мы там разместили один массив букв то у нас с выводом будет всё ок если компилятор своей инфы туда не добавит

Добавлено через 3 минуты
Цитата Сообщение от Cool-T Посмотреть сообщение
Может в gcc уже некоторые фичи из c++11 реализованы? Например "массив знает свой размер".
нет не знает. для ограничения массива используют либо второй параметр либо в конце ставят условный символ\набор символов которые служат сигналом о окончании массива. первый способ жрёт на 4 байта больше памяти за то гораздо быстрей обрабатывается(то есть там отключена проверка элемента массива на на окончание, ведь размер передается аргументом функции)
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
16.03.2012, 23:55     Семантика массивов char. #19
Цитата Сообщение от Van111 Посмотреть сообщение
(то есть там отключена проверка элемента массива на на окончание, ведь размер передается аргументом функции)
Почему же? Ведь переменная счетчик точно так же сравнивается с размером на каждой итерации.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.03.2012, 10:54     Семантика массивов char.
Еще ссылки по теме:

C++ Сложение двух динамических массивов char* в одну строку
C++ Перемножение столбиком двух массивов char
Передача в функции массивов типа char - ошибка C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ligorlwow
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 19
17.03.2012, 10:54  [ТС]     Семантика массивов char. #20
Цитата Сообщение от Van111 Посмотреть сообщение
для ограничения массива используют либо второй параметр либо в конце ставят условный символ\набор символов которые служат сигналом о окончании массива
Но проблема заключалась именно в том, что указывая размерность массива.. я получаю некорректный вывод... Мне не жалко 4 байтов для указания размера массива, но даже указав размер, я не получаю должно результата.
Yandex
Объявления
17.03.2012, 10:54     Семантика массивов char.
Ответ Создать тему
Опции темы

Текущее время: 20:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru