Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Вопросы по С/С++ (СИ)

Сообщение uk8amk »

Если рассматривать с точки зрения машины, то будет примерно следующее.
Пусть байтовый массив находится в памяти по адресу N. Чтобы адресовать самый первый элемент(байт), надо выставить адрес N+0. Второй байт - N+1 и т.д. Таким образом, обращение к элементу массива - есть фактически указание смещения относительно его начала(первого элемента).
Реклама
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Re: Вопросы по С/С++ (СИ)

Сообщение Siarzhuk »

FreshMan писал(а):кто-либо осведомлен, почему элементы массива нумеруются с нуля а не с единицы ? :)
Это не номера - это смещения. Это консистентно с арифметикой указателей. Это соответствует представлению данных в памяти. Это удобно в конце концов. ;-)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

FreshMan писал(а):кто-либо осведомлен, почему элементы массива нумеруются с нуля а не с единицы ? :)
Siarzhuk писал(а):Это не номера - это смещения. Это консистентно с арифметикой указателей. Это соответствует представлению данных в памяти. Это удобно в конце концов. ;-)
uk8amk писал(а):Если рассматривать с точки зрения машины, то будет примерно следующее.Пусть байтовый массив находится в памяти по адресу N. Чтобы адресовать самый первый элемент(байт), надо выставить адрес N+0. Второй байт - N+1 и т.д. Таким образом, обращение к элементу массива - есть фактически указание смещения относительно его начала(первого элемента).
удобно или нет - дело исключительно привычки, а вот по поводу смещения - просто только для байтовой адресации, а для данных, размер которых не равен байту, все уже не совсем так просто. попытка назвать внутреннее представление данных с "естественным" разбивается о человеческий мир материальных вещей, где исключительно все нумеруется с 1.

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

Мой уютный бложик... заходите!
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Re: Вопросы по С/С++ (СИ)

Сообщение Siarzhuk »

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: Вопросы по С/С++ (СИ)

Сообщение ARV »

Siarzhuk писал(а):Арифметика указателей принимает во внимание размер указуемых объектов. Нет никакой разницы содержится ли в массиве байты или сложные структуры - инкрементируя указатель на первый элемент массива вы получаете указатель на следующий элемент.
очевидные вещи говорите - и чо?
Siarzhuk писал(а):Кроме того манипулируя типом указателя можно работать с данными гораздо компактнее.
вообще не ясно, как одно связано с другим.

все эти рассказы про арифметику указателей не отвечают на кардинальный вопрос: почему в массиве домов мы должны первый дом нумеровать нулем?! если мы считаем ноги, то покажите мне кошачью ногу номер 0! :)))
в данном контексте проще - однозначно "нумеровать с 1"!

если бы изобретатель языка счел нужным взять за основу логику человека, массивы нумеровались бы с 1-го элемента, и это никак не изменило бы ничего. он счел возможным поступить иначе...

поэтому с моей точки зрения единственно правильный ответ на вопрос "почему с нуля" заключается в сакраментальном "потому что". такой язык Си.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Re: Вопросы по С/С++ (СИ)

Сообщение Siarzhuk »

ARV писал(а):однако, это не имеет отношения к сути: связь между индексом и адресом устанавливается компилятором, и чисто теоретически абсолютно все равно, как именно нумеровать элементы - дело заключается в двух вещах: стандарт языка и привычка программиста.
Суть в том и состоит что стандарт языка С предлагает использовать понятия физически существующей организации данных а не возводить дополнительный уровень адресации на ровном месте. Вот из этой естественности концепций и проистекают уже упомянутые удобство* использования и непротиворечивость остальным концепциям.

* Ну если конечно ещё можно говорить о каком-то удобстве средства разработки уходящего корнями в 60-ые годы прошедшего века. ;-)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

Siarzhuk писал(а):Суть в том и состоит что стандарт языка С предлагает использовать понятия физически существующей организации данных а не возводить дополнительный уровень адресации на ровном месте.
в том то и дело, что физически адресное пространство строго линейное и адресуется исключительно машинными словами. форматирование данных по типам, структурам и массивам - это уже более высокий уровень абстракции (мы уходим от машинных слов к "челвекоудобным" понятиям), поэтому ваше утверждение не совсем корректно.

вот по поводу стандарта - соглашусь полностью, но это и есть мой вариант ответа: сказано с 0, значит с 0 - и без вопросов! :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Re: Вопросы по С/С++ (СИ)

Сообщение Siarzhuk »

ARV писал(а):а вот по поводу смещения - просто только для байтовой адресации, а для данных, размер которых не равен байту, все уже не совсем так просто.
ARV писал(а):
Siarzhuk писал(а): Нет, именно смещение. Арифметика указателей принимает во внимание размер указуемых объектов. Нет никакой разницы содержится ли в массиве байты или сложные структуры - инкрементируя указатель на первый элемент массива вы получаете указатель на следующий элемент.
очевидные вещи говорите - и чо?
А это был ответ на ваше "не совсем так просто". С примером, что размер элемента значения не имеет и всё абсолютно идентично что для байтов, что для сложных структур.
ARV писал(а):
Siarzhuk писал(а):Кроме того манипулируя типом указателя можно работать с данными гораздо компактнее.
вообще не ясно, как одно связано с другим.
Приводя указатель к требуемым типам данным не нужно заморачиваться размерами структур а просто использовать адресную арифметику. Задача отслеживания размеров структур ложится на компилятор - что упрощает поддержку и доработку программы в будущем.
ARV писал(а):все эти рассказы про арифметику указателей
Это не рассказы - это объективная и непротиворечивая концепция представления данных.
ARV писал(а):не отвечают на кардинальный вопрос: почему в массиве домов мы должны первый дом нумеровать нулем?!
Потому что номер дома лучше хранить без привязки к индексу а как поле описывающей его структуры. Интересно что вы будете делать если гады-уплотнители на месте парка перед вашими окнами вопрут какой-нибудь дом "1б".
ARV писал(а):если мы считаем ноги, то покажите мне кошачью ногу номер 0! :)))
в данном контексте проще - однозначно "нумеровать с 1"!
Не ну коты - это другое дело на них никакие правила и языки не распространяются - контекст у них завсегда и везде повсюду свой.
ARV писал(а):если бы изобретатель языка счел нужным взять за основу логику человека, массивы нумеровались бы с 1-го элемента, и это никак не изменило бы ничего.


Помилуйте, там и так достаточно костылей чтобы вводить ещё один абсолютно ненужный "один пишем ноль в уме".
ARV писал(а):он счел возможным поступить иначе...

поэтому с моей точки зрения единственно правильный ответ на вопрос "почему с нуля" заключается в сакраментальном "потому что". такой язык Си.
Ну супротив религиозного сознания не попрёшь. ;-)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Re: Вопросы по С/С++ (СИ)

Сообщение Siarzhuk »

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

вот по поводу стандарта - соглашусь полностью, но это и есть мой вариант ответа: сказано с 0, значит с 0 - и без вопросов! :)))
Акей. :-)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

нашол документальное подтверждение :tea:
Изображение
Вложения
Выделение_008.png
(118.53 КБ) 636 скачиваний
Tell Me The Truth
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Вопросы по С/С++ (СИ)

Сообщение Kavka »

FreshMan, обратите внимание на следующее.
Напримере для x86 платформы. Указатель это адрес байта в памяти. И если взять указатель на uint32_t, то инкремент такого указателя на единицу приведёт к увеличению байтового адреса на sizeof(uint32_t). Что тоже показано (косвенно) на приведённой вами картинке.
Это будет справедливо для любой платформы с учётом её особенностей.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
slavokhire5
Прорезались зубы
Сообщения: 202
Зарегистрирован: Пн сен 26, 2011 13:48:25
Откуда: Харьков

Re: Вопросы по С/С++ (СИ)

Сообщение slavokhire5 »

Здравствуйте коты:)
Пытаюсь запустить пример webclient на uip, под CooCox, там есть такая конструкция:

void *uip_appdata;
...
++((char *)uip_appdata); // я так понимаю, это инкремент указателя

На строчку с инкрементом ругается: error: lvalue required as increment operand
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

чем плох вариант uip_appdata++; ???
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

ARV писал(а):uip_appdata++; ???
А даст ли компилятор это сделать ?
На сколько я понимаю, указатель на void - указатель на "неизвестно чего". Соответственно, для инкремента компилятору нужно знать размер этого "неизвестно чего".
Возможно, я ошибаюсь, и по стандарту void* - указатель на байт ? :dont_know:
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

Аlex писал(а):по стандарту void* - указатель на байт ? :dont_know:
указатель void* трактуется именно как указатель на байт
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Спасибо, поимею ввиду.
Аватара пользователя
GARMIN
Держит паяльник хвостом
Сообщения: 954
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение GARMIN »

Вопрос по применению макроса.
IAR, Си, STM8S

Задача следующая:
- у меня есть переменная системного времени sys_time, которая тикает по прерыванию таймера.
Я хочу безопасно пользоваться этой величиной.

Вначале я сделал такую функцию:

Код: Выделить всё

inline uint16_t time (void)
{
	return sys_time;
}
И пользовался вызовом:

Код: Выделить всё

LED_start_time = time ();
Переменная sys_time объявлена статической в файле таймеров и защищена от изменения извне. Возможно только чтение.
Но ИАР не хочет инлайнить функцию в простое обращение к памяти. Вызывает call даже при максимальной оптимизации. Перенос переменной в глобальную область видимости не помогает.
Применение #pragma inline = forsed тоже не помогает.
Я попробовал сделать дефайн

Код: Выделить всё

#define SYS_TIME(t)	(t = sys_time)
и вызываю его в программе:

Код: Выделить всё

	uint16_t	dt;
		LED_start_time = SYS_TIME(dt);
Так в ассемблере макрос превращается в обращение к памяти, но остаётся пустая переменная dt, на которую жалуется компилятор.
Как правильно поступить в такой ситуации?
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: Вопросы по С/С++ (СИ)

Сообщение HHIMERA »

Прочитать жалобу компилятора...
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

GARMIN писал(а): Я попробовал сделать дефайн

Код: Выделить всё

#define SYS_TIME(t)	(t = sys_time)
и вызываю его в программе:

Код: Выделить всё

	uint16_t	dt;
		LED_start_time = SYS_TIME(dt);
Так в ассемблере макрос превращается в обращение к памяти, но остаётся пустая переменная dt, на которую жалуется компилятор.
Как правильно поступить в такой ситуации?
ну так по-вашему выходит, что макрос надо использовать так: SYS_TIME(LED_start_time);

только у меня вопрос: нафига все это?! инлайнить функцию из другого модуля компилятор по идее не будет все равно...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
GARMIN
Держит паяльник хвостом
Сообщения: 954
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение GARMIN »

HHIMERA писал(а):Прочитать жалобу компилятора...
dt становится неиспользуемой переменной. Присваивание идёт настоящей переменной. dt нужна для того, чтобы исключить случайную запись в sys_time.
Что, никто не сталкивался с защитой переменных?
Может, ЛИ что подскажет.
Вообще, я хочу такую функцию, которая бы раскрывалась в код:

Код: Выделить всё

    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)
{}
Ответить

Вернуться в «Разные вопросы по МК»