Вопросы по С/С++ (СИ)
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Если рассматривать с точки зрения машины, то будет примерно следующее.
Пусть байтовый массив находится в памяти по адресу N. Чтобы адресовать самый первый элемент(байт), надо выставить адрес N+0. Второй байт - N+1 и т.д. Таким образом, обращение к элементу массива - есть фактически указание смещения относительно его начала(первого элемента).
Пусть байтовый массив находится в памяти по адресу N. Чтобы адресовать самый первый элемент(байт), надо выставить адрес N+0. Второй байт - N+1 и т.д. Таким образом, обращение к элементу массива - есть фактически указание смещения относительно его начала(первого элемента).
- Реклама
Re: Вопросы по С/С++ (СИ)
Это не номера - это смещения. Это консистентно с арифметикой указателей. Это соответствует представлению данных в памяти. Это удобно в конце концов.FreshMan писал(а):кто-либо осведомлен, почему элементы массива нумеруются с нуля а не с единицы ?
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18675
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
FreshMan писал(а):кто-либо осведомлен, почему элементы массива нумеруются с нуля а не с единицы ?
Siarzhuk писал(а):Это не номера - это смещения. Это консистентно с арифметикой указателей. Это соответствует представлению данных в памяти. Это удобно в конце концов.
удобно или нет - дело исключительно привычки, а вот по поводу смещения - просто только для байтовой адресации, а для данных, размер которых не равен байту, все уже не совсем так просто. попытка назвать внутреннее представление данных с "естественным" разбивается о человеческий мир материальных вещей, где исключительно все нумеруется с 1.uk8amk писал(а):Если рассматривать с точки зрения машины, то будет примерно следующее.Пусть байтовый массив находится в памяти по адресу N. Чтобы адресовать самый первый элемент(байт), надо выставить адрес N+0. Второй байт - N+1 и т.д. Таким образом, обращение к элементу массива - есть фактически указание смещения относительно его начала(первого элемента).
однако, это не имеет отношения к сути: связь между индексом и адресом устанавливается компилятором, и чисто теоретически абсолютно все равно, как именно нумеровать элементы - дело заключается в двух вещах: стандарт языка и привычка программиста.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Нет, именно смещение. Арифметика указателей принимает во внимание размер указуемых объектов. Нет никакой разницы содержится ли в массиве байты или сложные структуры - инкрементируя указатель на первый элемент массива вы получаете указатель на следующий элемент.ARV писал(а):а вот по поводу смещения - просто только для байтовой адресации, а для данных, размер которых не равен байту, все уже не совсем так просто.
Код: Выделить всё
struct S {
int a;
} a[10];
struct S* p = a;
for (i = 0; i < 10; i++, p++)
p->a = i;
// равнозначно следующему циклу
for (i = 0; i <10; i++)
a[i].a = i;
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18675
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
очевидные вещи говорите - и чо?Siarzhuk писал(а):Арифметика указателей принимает во внимание размер указуемых объектов. Нет никакой разницы содержится ли в массиве байты или сложные структуры - инкрементируя указатель на первый элемент массива вы получаете указатель на следующий элемент.
вообще не ясно, как одно связано с другим.Siarzhuk писал(а):Кроме того манипулируя типом указателя можно работать с данными гораздо компактнее.
все эти рассказы про арифметику указателей не отвечают на кардинальный вопрос: почему в массиве домов мы должны первый дом нумеровать нулем?! если мы считаем ноги, то покажите мне кошачью ногу номер 0!
в данном контексте проще - однозначно "нумеровать с 1"!
если бы изобретатель языка счел нужным взять за основу логику человека, массивы нумеровались бы с 1-го элемента, и это никак не изменило бы ничего. он счел возможным поступить иначе...
поэтому с моей точки зрения единственно правильный ответ на вопрос "почему с нуля" заключается в сакраментальном "потому что". такой язык Си.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
Re: Вопросы по С/С++ (СИ)
Суть в том и состоит что стандарт языка С предлагает использовать понятия физически существующей организации данных а не возводить дополнительный уровень адресации на ровном месте. Вот из этой естественности концепций и проистекают уже упомянутые удобство* использования и непротиворечивость остальным концепциям.ARV писал(а):однако, это не имеет отношения к сути: связь между индексом и адресом устанавливается компилятором, и чисто теоретически абсолютно все равно, как именно нумеровать элементы - дело заключается в двух вещах: стандарт языка и привычка программиста.
* Ну если конечно ещё можно говорить о каком-то удобстве средства разработки уходящего корнями в 60-ые годы прошедшего века.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18675
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
в том то и дело, что физически адресное пространство строго линейное и адресуется исключительно машинными словами. форматирование данных по типам, структурам и массивам - это уже более высокий уровень абстракции (мы уходим от машинных слов к "челвекоудобным" понятиям), поэтому ваше утверждение не совсем корректно.Siarzhuk писал(а):Суть в том и состоит что стандарт языка С предлагает использовать понятия физически существующей организации данных а не возводить дополнительный уровень адресации на ровном месте.
вот по поводу стандарта - соглашусь полностью, но это и есть мой вариант ответа: сказано с 0, значит с 0 - и без вопросов!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
ARV писал(а):а вот по поводу смещения - просто только для байтовой адресации, а для данных, размер которых не равен байту, все уже не совсем так просто.
А это был ответ на ваше "не совсем так просто". С примером, что размер элемента значения не имеет и всё абсолютно идентично что для байтов, что для сложных структур.ARV писал(а):очевидные вещи говорите - и чо?Siarzhuk писал(а): Нет, именно смещение. Арифметика указателей принимает во внимание размер указуемых объектов. Нет никакой разницы содержится ли в массиве байты или сложные структуры - инкрементируя указатель на первый элемент массива вы получаете указатель на следующий элемент.
Приводя указатель к требуемым типам данным не нужно заморачиваться размерами структур а просто использовать адресную арифметику. Задача отслеживания размеров структур ложится на компилятор - что упрощает поддержку и доработку программы в будущем.ARV писал(а):вообще не ясно, как одно связано с другим.Siarzhuk писал(а):Кроме того манипулируя типом указателя можно работать с данными гораздо компактнее.
Это не рассказы - это объективная и непротиворечивая концепция представления данных.ARV писал(а):все эти рассказы про арифметику указателей
Потому что номер дома лучше хранить без привязки к индексу а как поле описывающей его структуры. Интересно что вы будете делать если гады-уплотнители на месте парка перед вашими окнами вопрут какой-нибудь дом "1б".ARV писал(а):не отвечают на кардинальный вопрос: почему в массиве домов мы должны первый дом нумеровать нулем?!
Не ну коты - это другое дело на них никакие правила и языки не распространяются - контекст у них завсегда и везде повсюду свой.ARV писал(а):если мы считаем ноги, то покажите мне кошачью ногу номер 0!![]()
в данном контексте проще - однозначно "нумеровать с 1"!
ARV писал(а):если бы изобретатель языка счел нужным взять за основу логику человека, массивы нумеровались бы с 1-го элемента, и это никак не изменило бы ничего.
Помилуйте, там и так достаточно костылей чтобы вводить ещё один абсолютно ненужный "один пишем ноль в уме".
Ну супротив религиозного сознания не попрёшь.ARV писал(а):он счел возможным поступить иначе...
поэтому с моей точки зрения единственно правильный ответ на вопрос "почему с нуля" заключается в сакраментальном "потому что". такой язык Си.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Акей.ARV писал(а):в том то и дело, что физически адресное пространство строго линейное и адресуется исключительно машинными словами. форматирование данных по типам, структурам и массивам - это уже более высокий уровень абстракции (мы уходим от машинных слов к "челвекоудобным" понятиям), поэтому ваше утверждение не совсем корректно.
вот по поводу стандарта - соглашусь полностью, но это и есть мой вариант ответа: сказано с 0, значит с 0 - и без вопросов!
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
нашол документальное подтверждение

- Вложения
-
- Выделение_008.png
- (118.53 КБ) 636 скачиваний
Tell Me The Truth
Re: Вопросы по С/С++ (СИ)
FreshMan, обратите внимание на следующее.
Напримере для x86 платформы. Указатель это адрес байта в памяти. И если взять указатель на uint32_t, то инкремент такого указателя на единицу приведёт к увеличению байтового адреса на sizeof(uint32_t). Что тоже показано (косвенно) на приведённой вами картинке.
Это будет справедливо для любой платформы с учётом её особенностей.
Напримере для x86 платформы. Указатель это адрес байта в памяти. И если взять указатель на uint32_t, то инкремент такого указателя на единицу приведёт к увеличению байтового адреса на sizeof(uint32_t). Что тоже показано (косвенно) на приведённой вами картинке.
Это будет справедливо для любой платформы с учётом её особенностей.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- slavokhire5
- Прорезались зубы
- Сообщения: 202
- Зарегистрирован: Пн сен 26, 2011 13:48:25
- Откуда: Харьков
Re: Вопросы по С/С++ (СИ)
Здравствуйте коты:)
Пытаюсь запустить пример webclient на uip, под CooCox, там есть такая конструкция:
void *uip_appdata;
...
++((char *)uip_appdata); // я так понимаю, это инкремент указателя
На строчку с инкрементом ругается: error: lvalue required as increment operand
Пытаюсь запустить пример webclient на uip, под CooCox, там есть такая конструкция:
void *uip_appdata;
...
++((char *)uip_appdata); // я так понимаю, это инкремент указателя
На строчку с инкрементом ругается: error: lvalue required as increment operand
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
--------------------------
Пишу на Си за еду
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18675
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
чем плох вариант uip_appdata++; ???
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
А даст ли компилятор это сделать ?ARV писал(а):uip_appdata++; ???
На сколько я понимаю, указатель на void - указатель на "неизвестно чего". Соответственно, для инкремента компилятору нужно знать размер этого "неизвестно чего".
Возможно, я ошибаюсь, и по стандарту void* - указатель на байт ?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18675
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
указатель void* трактуется именно как указатель на байтАlex писал(а):по стандарту void* - указатель на байт ?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Спасибо, поимею ввиду.
- GARMIN
- Держит паяльник хвостом
- Сообщения: 954
- Зарегистрирован: Вс дек 02, 2012 16:58:33
- Откуда: от туда
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Вопрос по применению макроса.
IAR, Си, STM8S
Задача следующая:
- у меня есть переменная системного времени sys_time, которая тикает по прерыванию таймера.
Я хочу безопасно пользоваться этой величиной.
Вначале я сделал такую функцию:
И пользовался вызовом:
Переменная sys_time объявлена статической в файле таймеров и защищена от изменения извне. Возможно только чтение.
Но ИАР не хочет инлайнить функцию в простое обращение к памяти. Вызывает call даже при максимальной оптимизации. Перенос переменной в глобальную область видимости не помогает.
Применение #pragma inline = forsed тоже не помогает.
Я попробовал сделать дефайн
и вызываю его в программе:
Так в ассемблере макрос превращается в обращение к памяти, но остаётся пустая переменная dt, на которую жалуется компилятор.
Как правильно поступить в такой ситуации?
IAR, Си, STM8S
Задача следующая:
- у меня есть переменная системного времени sys_time, которая тикает по прерыванию таймера.
Я хочу безопасно пользоваться этой величиной.
Вначале я сделал такую функцию:
Код: Выделить всё
inline uint16_t time (void)
{
return sys_time;
}Код: Выделить всё
LED_start_time = time ();Но ИАР не хочет инлайнить функцию в простое обращение к памяти. Вызывает call даже при максимальной оптимизации. Перенос переменной в глобальную область видимости не помогает.
Применение #pragma inline = forsed тоже не помогает.
Я попробовал сделать дефайн
Код: Выделить всё
#define SYS_TIME(t) (t = sys_time)
Код: Выделить всё
uint16_t dt;
LED_start_time = SYS_TIME(dt);
Как правильно поступить в такой ситуации?
Re: Вопросы по С/С++ (СИ)
Прочитать жалобу компилятора...
"Я не даю готовых решений, я заставляю думать!"(С)
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18675
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
ну так по-вашему выходит, что макрос надо использовать так: SYS_TIME(LED_start_time);GARMIN писал(а): Я попробовал сделать дефайни вызываю его в программе:Код: Выделить всё
#define SYS_TIME(t) (t = sys_time)Так в ассемблере макрос превращается в обращение к памяти, но остаётся пустая переменная dt, на которую жалуется компилятор.Код: Выделить всё
uint16_t dt; LED_start_time = SYS_TIME(dt);
Как правильно поступить в такой ситуации?
только у меня вопрос: нафига все это?! инлайнить функцию из другого модуля компилятор по идее не будет все равно...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- GARMIN
- Держит паяльник хвостом
- Сообщения: 954
- Зарегистрирован: Вс дек 02, 2012 16:58:33
- Откуда: от туда
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
dt становится неиспользуемой переменной. Присваивание идёт настоящей переменной. dt нужна для того, чтобы исключить случайную запись в sys_time.HHIMERA писал(а):Прочитать жалобу компилятора...
Что, никто не сталкивался с защитой переменных?
Может, ЛИ что подскажет.
Вообще, я хочу такую функцию, которая бы раскрывалась в код:
Код: Выделить всё
221 disableInterrupts();
\ 00002E 9B SIM
222 LED_start_time = SYS_TIME(dt);
\ 00002F CE .... LDW X, L:sys_time
\ 000032 CF .... LDW L:LED_start_time, X
223 enableInterrupts();
\ 000035 9A RIMКод: Выделить всё
if ((SYS_TIME(dt) - LED_start_time) > TIME_DISPLAY_CHANNEL)
{}

