Пусть байтовый массив находится в памяти по адресу N. Чтобы адресовать самый первый элемент(байт), надо выставить адрес N+0. Второй байт - N+1 и т.д. Таким образом, обращение к элементу массива - есть фактически указание смещения относительно его начала(первого элемента).
Вопросы по С/С++ (СИ)
Если рассматривать с точки зрения машины, то будет примерно следующее.
Пусть байтовый массив находится в памяти по адресу N. Чтобы адресовать самый первый элемент(байт), надо выставить адрес N+0. Второй байт - N+1 и т.д. Таким образом, обращение к элементу массива - есть фактически указание смещения относительно его начала(первого элемента).
Пусть байтовый массив находится в памяти по адресу N. Чтобы адресовать самый первый элемент(байт), надо выставить адрес N+0. Второй байт - N+1 и т.д. Таким образом, обращение к элементу массива - есть фактически указание смещения относительно его начала(первого элемента).
- Реклама
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Это не номера - это смещения. Это консистентно с арифметикой указателей. Это соответствует представлению данных в памяти. Это удобно в конце концов.FreshMan писал(а):кто-либо осведомлен, почему элементы массива нумеруются с нуля а не с единицы ?
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
FreshMan писал(а):кто-либо осведомлен, почему элементы массива нумеруются с нуля а не с единицы ?
Siarzhuk писал(а):Это не номера - это смещения. Это консистентно с арифметикой указателей. Это соответствует представлению данных в памяти. Это удобно в конце концов.
удобно или нет - дело исключительно привычки, а вот по поводу смещения - просто только для байтовой адресации, а для данных, размер которых не равен байту, все уже не совсем так просто. попытка назвать внутреннее представление данных с "естественным" разбивается о человеческий мир материальных вещей, где исключительно все нумеруется с 1.uk8amk писал(а):Если рассматривать с точки зрения машины, то будет примерно следующее.Пусть байтовый массив находится в памяти по адресу N. Чтобы адресовать самый первый элемент(байт), надо выставить адрес N+0. Второй байт - N+1 и т.д. Таким образом, обращение к элементу массива - есть фактически указание смещения относительно его начала(первого элемента).
однако, это не имеет отношения к сути: связь между индексом и адресом устанавливается компилятором, и чисто теоретически абсолютно все равно, как именно нумеровать элементы - дело заключается в двух вещах: стандарт языка и привычка программиста.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Нет, именно смещение. Арифметика указателей принимает во внимание размер указуемых объектов. Нет никакой разницы содержится ли в массиве байты или сложные структуры - инкрементируя указатель на первый элемент массива вы получаете указатель на следующий элемент.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! 
очевидные вещи говорите - и чо?Siarzhuk писал(а):Арифметика указателей принимает во внимание размер указуемых объектов. Нет никакой разницы содержится ли в массиве байты или сложные структуры - инкрементируя указатель на первый элемент массива вы получаете указатель на следующий элемент.
вообще не ясно, как одно связано с другим.Siarzhuk писал(а):Кроме того манипулируя типом указателя можно работать с данными гораздо компактнее.
все эти рассказы про арифметику указателей не отвечают на кардинальный вопрос: почему в массиве домов мы должны первый дом нумеровать нулем?! если мы считаем ноги, то покажите мне кошачью ногу номер 0!
в данном контексте проще - однозначно "нумеровать с 1"!
если бы изобретатель языка счел нужным взять за основу логику человека, массивы нумеровались бы с 1-го элемента, и это никак не изменило бы ничего. он счел возможным поступить иначе...
поэтому с моей точки зрения единственно правильный ответ на вопрос "почему с нуля" заключается в сакраментальном "потому что". такой язык Си.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Суть в том и состоит что стандарт языка С предлагает использовать понятия физически существующей организации данных а не возводить дополнительный уровень адресации на ровном месте. Вот из этой естественности концепций и проистекают уже упомянутые удобство* использования и непротиворечивость остальным концепциям.ARV писал(а):однако, это не имеет отношения к сути: связь между индексом и адресом устанавливается компилятором, и чисто теоретически абсолютно все равно, как именно нумеровать элементы - дело заключается в двух вещах: стандарт языка и привычка программиста.
* Ну если конечно ещё можно говорить о каком-то удобстве средства разработки уходящего корнями в 60-ые годы прошедшего века.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
в том то и дело, что физически адресное пространство строго линейное и адресуется исключительно машинными словами. форматирование данных по типам, структурам и массивам - это уже более высокий уровень абстракции (мы уходим от машинных слов к "челвекоудобным" понятиям), поэтому ваше утверждение не совсем корректно.Siarzhuk писал(а):Суть в том и состоит что стандарт языка С предлагает использовать понятия физически существующей организации данных а не возводить дополнительный уровень адресации на ровном месте.
вот по поводу стандарта - соглашусь полностью, но это и есть мой вариант ответа: сказано с 0, значит с 0 - и без вопросов!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
ARV писал(а):а вот по поводу смещения - просто только для байтовой адресации, а для данных, размер которых не равен байту, все уже не совсем так просто.
А это был ответ на ваше "не совсем так просто". С примером, что размер элемента значения не имеет и всё абсолютно идентично что для байтов, что для сложных структур.ARV писал(а):очевидные вещи говорите - и чо?Siarzhuk писал(а): Нет, именно смещение. Арифметика указателей принимает во внимание размер указуемых объектов. Нет никакой разницы содержится ли в массиве байты или сложные структуры - инкрементируя указатель на первый элемент массива вы получаете указатель на следующий элемент.
Приводя указатель к требуемым типам данным не нужно заморачиваться размерами структур а просто использовать адресную арифметику. Задача отслеживания размеров структур ложится на компилятор - что упрощает поддержку и доработку программы в будущем.ARV писал(а):вообще не ясно, как одно связано с другим.Siarzhuk писал(а):Кроме того манипулируя типом указателя можно работать с данными гораздо компактнее.
Это не рассказы - это объективная и непротиворечивая концепция представления данных.ARV писал(а):все эти рассказы про арифметику указателей
Потому что номер дома лучше хранить без привязки к индексу а как поле описывающей его структуры. Интересно что вы будете делать если гады-уплотнители на месте парка перед вашими окнами вопрут какой-нибудь дом "1б".ARV писал(а):не отвечают на кардинальный вопрос: почему в массиве домов мы должны первый дом нумеровать нулем?!
Не ну коты - это другое дело на них никакие правила и языки не распространяются - контекст у них завсегда и везде повсюду свой.ARV писал(а):если мы считаем ноги, то покажите мне кошачью ногу номер 0!![]()
в данном контексте проще - однозначно "нумеровать с 1"!
ARV писал(а):если бы изобретатель языка счел нужным взять за основу логику человека, массивы нумеровались бы с 1-го элемента, и это никак не изменило бы ничего.
Помилуйте, там и так достаточно костылей чтобы вводить ещё один абсолютно ненужный "один пишем ноль в уме".
Ну супротив религиозного сознания не попрёшь.ARV писал(а):он счел возможным поступить иначе...
поэтому с моей точки зрения единственно правильный ответ на вопрос "почему с нуля" заключается в сакраментальном "потому что". такой язык Си.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Акей.ARV писал(а):в том то и дело, что физически адресное пространство строго линейное и адресуется исключительно машинными словами. форматирование данных по типам, структурам и массивам - это уже более высокий уровень абстракции (мы уходим от машинных слов к "челвекоудобным" понятиям), поэтому ваше утверждение не совсем корректно.
вот по поводу стандарта - соглашусь полностью, но это и есть мой вариант ответа: сказано с 0, значит с 0 - и без вопросов!
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
нашол документальное подтверждение

- Вложения
-
- Выделение_008.png
- (118.53 КБ) 645 скачиваний
Tell Me The Truth
FreshMan, обратите внимание на следующее.
Напримере для x86 платформы. Указатель это адрес байта в памяти. И если взять указатель на uint32_t, то инкремент такого указателя на единицу приведёт к увеличению байтового адреса на sizeof(uint32_t). Что тоже показано (косвенно) на приведённой вами картинке.
Это будет справедливо для любой платформы с учётом её особенностей.
Напримере для x86 платформы. Указатель это адрес байта в памяти. И если взять указатель на uint32_t, то инкремент такого указателя на единицу приведёт к увеличению байтового адреса на sizeof(uint32_t). Что тоже показано (косвенно) на приведённой вами картинке.
Это будет справедливо для любой платформы с учётом её особенностей.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Здравствуйте коты:)
Пытаюсь запустить пример 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
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
--------------------------
Пишу на Си за еду
чем плох вариант uip_appdata++; ???
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
А даст ли компилятор это сделать ?ARV писал(а):uip_appdata++; ???
На сколько я понимаю, указатель на void - указатель на "неизвестно чего". Соответственно, для инкремента компилятору нужно знать размер этого "неизвестно чего".
Возможно, я ошибаюсь, и по стандарту void* - указатель на байт ?
указатель void* трактуется именно как указатель на байтАlex писал(а):по стандарту void* - указатель на байт ?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Вопрос по применению макроса.
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);
Как правильно поступить в такой ситуации?
Прочитать жалобу компилятора...
"Я не даю готовых решений, я заставляю думать!"(С)
ну так по-вашему выходит, что макрос надо использовать так: SYS_TIME(LED_start_time);GARMIN писал(а): Я попробовал сделать дефайни вызываю его в программе:Код: Выделить всё
#define SYS_TIME(t) (t = sys_time)Так в ассемблере макрос превращается в обращение к памяти, но остаётся пустая переменная dt, на которую жалуется компилятор.Код: Выделить всё
uint16_t dt; LED_start_time = SYS_TIME(dt);
Как правильно поступить в такой ситуации?
только у меня вопрос: нафига все это?! инлайнить функцию из другого модуля компилятор по идее не будет все равно...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
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)
{}


