Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] "char* s = {'\0'}", бывает же... 
:(
    Опции темы
JackYF
Дата 16.8.2007, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Итак, мини-квест.

Имеем код:

Код

#include <cstdio>
int main(int argc, char* argv[])
{
  char* s = {'\0'};

  printf("%p\n", s);

  return 0;
}


Смотрим и пытаемся предугадать, что сделает этот код.

Потом запускаем свой любимый компилятор, загоняем в него код, компилируем, запускаем, материмся про себя, и пытаемся объяснить увиденное.
Я вот не смог.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Annihilator
Дата 16.8.2007, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


bytegrinder
**


Профиль
Группа: Участник
Сообщений: 493
Регистрация: 21.11.2006
Где: Омск

Репутация: 1
Всего: 3



Если компилятор обнаруживает строковый литерал, он сохраняет его в таблице строк программы и генерирует указатель на нужную строку.
При выполнении этой проги символы, образующие строковый литерал, сохраняются в таблице строк, а переменной s присваивается указатель на соответствующую строку в этой таблице


--------------------
Если вы не можете сделать хоpошyю пpогpаммy, сделайте, чтобы она по кpайней меpе выглядела хоpошо
PM ICQ   Вверх
zkv
Дата 16.8.2007, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 26
Всего: 92



Цитата(Annihilator @  16.8.2007,  18:51 Найти цитируемый пост)
Если компилятор обнаруживает строковый литерал

а где тут строковый литерал? Я вижу только {'\0'}, что эквивалентно {0}, этот пример сработает также:
Код

#include <cstdio>
int main(int argc, char* argv[])
{
  int i = {'\0'};
  printf("%p\n", i);
  return 0;
}

PM MAIL   Вверх
jonie
Дата 16.8.2007, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



Цитата

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

char* p;

тоже что и
Код

char p[1];

так что в чем проблемы-то?
----------
"тоже" всмысле раскрывания выражений компилятором ессна)

Это сообщение отредактировал(а) jonie - 16.8.2007, 19:13


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
JackYF
Дата 16.8.2007, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Annihilator, первый пункт выполнен на ура. Теперь выполняй второй smile (тот, который с участием компилятора).

Добавлено через 2 минуты и 13 секунд
Цитата(jonie @  16.8.2007,  19:12 Найти цитируемый пост)
а что такого-то? инициализация массива обычная

да, да. Я вот так тоже думал. Я не зря написал пункт про компиляцию и просмотр результата.

Добавлено через 8 минут и 56 секунд
Цитата(zkv @  16.8.2007,  19:08 Найти цитируемый пост)
а где тут строковый литерал? Я вижу только {'\0'}, что эквивалентно {0}

верно. Как выясняется, строкового литерала здесь нету.

Вопрос дальше: почему {0} эквивалентно 0 в данном случае? Учитывая, что в фигурные скобки берутся элементы списка инициализации массивов?

Ведь в случае char s[] = {'\0'}; происходит ожидаемая инициализация массива из одного элемента.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Annihilator
Дата 16.8.2007, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


bytegrinder
**


Профиль
Группа: Участник
Сообщений: 493
Регистрация: 21.11.2006
Где: Омск

Репутация: 1
Всего: 3



если напишем вот так
Код

printf("%s\n", s);

то выдаст NULL, получается мы инициализируем указатель NULL`ом


--------------------
Если вы не можете сделать хоpошyю пpогpаммy, сделайте, чтобы она по кpайней меpе выглядела хоpошо
PM ICQ   Вверх
jonie
Дата 16.8.2007, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



Цитата

В языке С константа 0, когда она распознается как указатель,
        преобразуется компилятором в нулевой указатель. То есть, если во
        время инициализации, присваивания или сравнения с одной стороны
        стоит переменная или выражение, имеющее тип указателя, компилятор
        решает, что константа 0 с другой стороны должна превратиться в
        нулевой указатель и генерирует нулевой указатель нужного типа.
потомуШта....
-----------------------
кстати  нулевой указатель вовсе не обязательно представляется двоичным нулем

Это сообщение отредактировал(а) jonie - 16.8.2007, 20:06


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
MAKCim
Дата 16.8.2007, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(JackYF @  16.8.2007,  19:13 Найти цитируемый пост)
Вопрос дальше: почему {0} эквивалентно 0 в данном случае? Учитывая, что в фигурные скобки берутся элементы списка инициализации массивов?

смотри
Код

int main() {
    int a = {0};
    return 0;
}

так что {0} = 0  smile

Добавлено через 1 минуту и 22 секунды
Цитата(jonie @  16.8.2007,  20:04 Найти цитируемый пост)
кстати  нулевой указатель вовсе не обязательно представляется двоичным нулем

не вижу смысла в обратном


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 16.8.2007, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(jonie @ 16.8.2007,  20:04)
кстати  нулевой указатель вовсе не обязательно представляется двоичным нулем

Боюсь, если какой-то умник сделает его не равным двоичному нулю, то куча прог перестанет работать, так как значение NULL станет истиной в булевых операциях.
PM   Вверх
MAKCim
Дата 16.8.2007, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



bsa, 
я всегда явно проверяю
Код

if (a == NULL);

 smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 16.8.2007, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



А вот сразу оптимизацией занимаюсь.  smile 
PM   Вверх
nickless
Дата 16.8.2007, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Мдя, а я попробовал на gcc... smile 
Я последния раз это слово видел, когда на дельфи программировал smile 


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Xenon
Дата 16.8.2007, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Макросы нерулез и кака smile


--------------------
user posted image  
PM MAIL   Вверх
jonie
Дата 16.8.2007, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



Цитата(bsa @ 16.8.2007,  21:05)
Цитата(jonie @ 16.8.2007,  20:04)
кстати  нулевой указатель вовсе не обязательно представляется двоичным нулем

Боюсь, если какой-то умник сделает его не равным двоичному нулю, то куча прог перестанет работать, так как значение NULL станет истиной в булевых операциях.

вы не поняли смысла моей цитаты.
нулевой указатель не обязательно нуль.
Цитата

так как значение NULL станет истиной в булевых операциях.
еслиб вы знали как компилятор рассматривает операцию !указатель то такого бы не сказали.
Цитата

if(p)        эквивалентно        if(p != 0)
и это случай, когда происходит сравнение, так что компилятор поймет,
        что неявный ноль - это нулевой указатель и будет использовать
        правильное значение. Здесь нет никакого подвоха, компиляторы работают
    именно так и генерируют    в обоих    случаях    идентичный код.    Внутреннее
    представление указателя    _не_ имеет значения.

Оператор логического отрицания ! может быть описан так:
!expr   на самом деле    эквивалентно    expr?0:1
....
язык гарантирует,
        что 0, встреченный там, где по контексту подразумевается указатель,
        будет заменен компилятором на нулевой указатель.


Цитата

1.11:    Почему так много путаницы связано с нулевыми указателями? Почему
    так часто возникают вопросы?

О:      Программисты на С традиционно хотят знать больше, чем это необходимо
        для программирования, о внутреннем представлении кода.  Тот факт,
        что внутреннее представление нулевых указателей для большинства
        машин совпадает с их представлением в исходном тексте, т.е. нулем,
        способствует появлению неверных обобщений. Использование макроса
        (NULL) предполагает, что значение может впоследствии измениться, или
        иметь другое значение для какого-нибудь компьютера.  Конструкция
        "if(p == 0)" может быть истолкована неверно, как преобразование перед
        сравнением p к целому типу, а не 0 к типу указателя.  Наконец, часто
        не замечают, что термин "null" употребляется в разных смыслах
        (перечисленных выше).

    Хороший    способ устранить путаницу - вообразить,    что язык С имеет
        ключевое слово (возможно, nil, как в Паскале), которое обозначает
        нулевой указатель. Компилятор либо пребразует "nil" в нулевой
        указатель нужного типа, либо сообщает об ошибке, когда этого сделать
    нельзя.    На самом деле, ключевое    слово для нулевого указателя в С
        - это не "nil" а "0". Это ключевое слово работает всегда, за
        исключением случая, когда компилятор воспринимает в неподходящем
    контексте "0" без указания типа    как целое число, равное    нулю, вместо
        того, чтобы сообщить об ошибке. Программа может не работать, если
        предполагалось, что "0" без явного указания типа - это нулевой
        указатель.

в общем читайте FAQ-и : http://faqs.org.ru/progr/c_cpp/cfaqrus.htm

Это сообщение отредактировал(а) jonie - 16.8.2007, 22:15


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
MAKCim
Дата 16.8.2007, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(jonie @  16.8.2007,  22:09 Найти цитируемый пост)
и это случай, когда происходит сравнение, так что компилятор поймет,
        что неявный ноль - это нулевой указатель и будет использовать
        правильное значение.

ты же сам написал
if (p) ~ if (p != 0)
если NULL != (void*)0, то if (p) = true
а это неправильно с учетом семантики NULL

Добавлено через 9 минут и 15 секунд
jonie, 
с ключевым словом понятно
это очевидно
но если, опять таки, предположить, что NULL != (void*)0
все операции вида if (p), if (!p) идут лесом


Это сообщение отредактировал(а) MAKCim - 16.8.2007, 22:29


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1246 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.