2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2
 
 Re: C++ не могу найти нужную функцию
Сообщение27.09.2009, 20:49 


21/03/06
1545
Москва
Цитата:
Ну да, строковые литералы соответствуют строкам с завершающим нулем, один символ лишний.

Да.

Цитата:
Вы имели ввиду, что символ может весить больше обычного восьмибитного байта? Или дело здесь в выравнивании?

Да.

Цитата:
Или в размере указателя (i.e. в разрядности машины)?

Нет.

А еще в том, что на некоторых архитектурах строки хранятся в энергонезависимой памяти, а непосредственно после запуска программы копируются в ОЗУ. Поэтому получаем в худшем случае 4 байта лишних.

 Профиль  
                  
 
 Re: C++ не могу найти нужную функцию
Сообщение28.09.2009, 00:18 
Заслуженный участник


26/07/09
1559
Алматы
Цитата:
Цитата:
Вы имели ввиду, что символ может весить больше обычного восьмибитного байта? Или дело здесь в выравнивании?
Да.

Простите, но получился диалог в духе: -- Черное или белое? -- Да. :)
Т.е. именно выравнивание может кушать лишние байты?

Цитата:
А еще в том, что на некоторых архитектурах строки хранятся в энергонезависимой памяти, а непосредственно после запуска программы копируются в ОЗУ. Поэтому получаем в худшем случае 4 байта лишних.

И опять я не понял... На любых ведь машинах статично распределенные строки обычно хранятся с исполняемым образом на энергонезависимом носителе (хард, флеш, неважно), а потом копируются (или лучше сказать, отображаются) в оперативную память. :)

Цитата:
Цитата:
Или в размере указателя (i.e. в разрядности машины)?
Нет.

Почему? На 16-ти разрядных компах указатели два байта весят, на 32-х разрядных -- 4 байта. В том примере с индексированием строки оптимизатор вроде-бы не обязан игнорировать арифметику указателей, и, возможно, даже указатель будет храниться именно в ОЗУ (а не в регистре или в CPU-инструкции чтения, используемой для доступа к строке).

Просветите, если не сложно, ok? Спасибо.

 Профиль  
                  
 
 Re: C++ не могу найти нужную функцию
Сообщение28.09.2009, 04:23 
Заслуженный участник


15/05/09
1563
Circiter в сообщении #245092 писал(а):
Дело в том, что в C/C++ конструкция вида <выражение1> [ <выражение2> ] просто является своеобразным синтаксическим сахаром (i.e. эквивалентна) для конструкции *( ( <выражение1> ) + ( <выражение2> ) ), таким образом странное поведение при индексировании массивов обусловлено коммутативностью оператора + (плюс).
Circiter в сообщении #245123 писал(а):
Because of the conversion rules that apply to +, if E1 is an array and E2 an integer, then E1 [E2] refers to the E2-th member of E1. Therefore, despite its asymmetric appearance, subscripting is a commutative operation.
Все это, разумеется, так, только есть одно "но". Реальный код, генерируемый компилятором, учитывает тип элементов массива - именно массива, и в этом уже нет никакой симметрии. В результате конструкция *( ( <выражение1> ) + ( <выражение2> ) ) отражает не всю правду: то выражение, которое является не адресом массива, на самом деле умножается на sizeof(array[0]). Попробуйте использовать вместо идентификатора массива void* :wink: и посмотреть, что скажет компилятор. Или преобразовать оба выражения 1 и 2 к целому...

Так что красивую симметрию, описанную стандартом, реализует компилятор. И вследствие умножения на sizeof почти вся "сахарность" исчезает - описание одного из идентификаторов как массива (указателя на определенный тип) принципиально важно.

Впрочем, для предложенных решений исходной задачи это выполняется автоматически. Решения, использующие индексацию строки, хоть и красивы с точки зрения демонстрации особенностей языка (грубо говоря, позволяют "выпендриться"), но менее очевидны, чем решение с условным выражением. Применение конструкций, адекватных задаче, является ИМХО хорошим стилем и залогом получения более надежного и самодокументирующегося кода. А эффективность того или иного решения зависит как от компилятора, так и от архитектуры процессора. И вообще, если выигрыш в несколько байт/инструкций столь важен, лучше оптимизировать критические участки применением языка ассемблера.

 Профиль  
                  
 
 Re: C++ не могу найти нужную функцию
Сообщение28.09.2009, 08:43 


21/03/06
1545
Москва
Circiter писал(а):
Просветите, если не сложно, ok? Спасибо.

Не сложно, но Вы ведь и сами все понимаете.

Circiter писал(а):
Простите, но получился диалог в духе: -- Черное или белое? -- Да.
Т.е. именно выравнивание может кушать лишние байты?

И выравнивание, и то, что тип char может занимать больше, чем 1 байт (8 бит).

Например, на 16-битных DSP-процессорах фирмы Texas Instruments, основанных на ядре TMS320 минимально адресуемое кол-во памяти - 16 бит, и его родной компилятор СИ хранит char в 16 битах, и sizeof(char) = sizeof(int) = 1.

Circiter писал(а):
И опять я не понял... На любых ведь машинах статично распределенные строки обычно хранятся с исполняемым образом на энергонезависимом носителе (хард, флеш, неважно), а потом копируются (или лучше сказать, отображаются) в оперативную память.

А чем Вам Flash не память? Да и пространство на HDD не бесконечно. И именно, что копируются. Отображать в ОЗУ адреса с flash технически сложно - flash массив обычно читается целыми большими секторами (64 килослова и т.п.), а HDD слишком медленный - не имеет смысла.

Circiter писал(а):
Почему? На 16-ти разрядных компах указатели два байта весят, на 32-х разрядных -- 4 байта. В том примере с индексированием строки оптимизатор вроде-бы не обязан игнорировать арифметику указателей, и, возможно, даже указатель будет храниться именно в ОЗУ (а не в регистре или в CPU-инструкции чтения, используемой для доступа к строке).

Да указатели тут непричем. Там идет просто константный массив последовательно расположенных объектов типа char, не имеющий даже собственного имени. Для этого не требуется использовать арифметику указателей, косвенная адресация на него будет уже в процессе выполнения кода, с использованием регистров процессора (если программа может динамически размещаться в памяти, т.е. "exe"; если программа со статическим размещением, то там вообще будет присутствовать абсолютный адрес этогой строки и все - программа типа "com").

-- Пн сен 28, 2009 08:55:20 --

PapaKarlo писал(а):
Все это, разумеется, так, только есть одно "но". Реальный код, генерируемый компилятором, учитывает тип элементов массива - именно массива, и в этом уже нет никакой симметрии. В результате конструкция *( ( <выражение1> ) + ( <выражение2> ) ) отражает не всю правду: то выражение, которое является не адресом массива, на самом деле умножается на sizeof(array[0]). Попробуйте использовать вместо идентификатора массива void* и посмотреть, что скажет компилятор. Или преобразовать оба выражения 1 и 2 к целому...

Извините, может быть потому, что сейчас утро понедельника, но никак не вникну, что Вы хотите сказать и в чем, по Вашему, заковыка.
И в случае индексации массива, и в случае операции сложения указателя определенного типа с целым, выполняется умножение на sizeof(array[0]). В чем проблема-то?

Использовать же в качестве типа элементов массива void естественно нельзя. Используя какой-нибудь второй указатель типа void * на заренее объявленный массив возможно, но для его индексации Вы вынуждены будете сами приводить его к какому-нибудь осмысленному типу. Приведя его к типу, отличному от типа элементов нашего массивы, Вы получите ерунду, когда размеры типов не совпадают. Другое дело, что обсуждалось то несколько иное.

 Профиль  
                  
 
 Re: C++ не могу найти нужную функцию
Сообщение28.09.2009, 11:32 
Заслуженный участник


15/05/09
1563
e2e4 в сообщении #247077 писал(а):
Извините, может быть потому, что сейчас утро понедельника, но никак не вникну, что Вы хотите сказать и в чем, по Вашему, заковыка.И в случае индексации массива, и в случае операции сложения указателя определенного типа с целым, выполняется умножение на sizeof(array[0]). В чем проблема-то?
Вы правы, особой заковыки нет. Просто сочетание ударения на симметрию операции сложения и ассимметрия операндов у меня вызвало некое чувство шероховатости, что-ли; я понимаю, что это очень субъективно. Использование указателя в качестве индекса действительно можно назвать побочным эффектом языка, т.к. в коде, генерируемом компилятором, реальной симметрии нет. Видимо, на моем восприятии сказывается кодирование управляющих программ на ассемблере (не для PC :) ).

 Профиль  
                  
 
 Re: C++ не могу найти нужную функцию
Сообщение02.10.2009, 22:30 
Аватара пользователя


02/10/09
5
Moscow
Очевидное решение без при-плюс-нутостей:
Код:
void
func (signed int n){
    printf("%c",(n<0)?'-':'+');
}

 Профиль  
                  
 
 Re: C++ не могу найти нужную функцию
Сообщение03.10.2009, 01:59 
Заслуженный участник


26/07/09
1559
Алматы
2MATAH
Цитата:
Очевидное решение без при-плюс-нутостей

Обратите внимание на заголовок темы. :)

К тому же в вашем решении форматная строка парсится в run-time, зачем?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу Пред.  1, 2

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group