Страница 166 из 386

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

Добавлено: Вс сен 15, 2013 20:20:13
FreshMan
и что нам это дает ?

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

Добавлено: Вс сен 15, 2013 20:30:26
ploop
(константы, переменные итп) - если их объявить static, они будут видны/доступны только из модуля в котором объявлены.
Один важный момент: static-переменные, объявленные локально, не теряют своего значения при выходе из функции.

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

Добавлено: Вс сен 15, 2013 20:35:38
FreshMan
coredumped писал(а):
FreshMan писал(а):в каких случаях перед названием ф-ции ставится префикс static ?
Если нужно ограничить видимость имени этой ф-ции модулем, в котором она объявлена. Это касается любых глобальных идентификаторов (константы, переменные итп) - если их объявить static, они будут видны/доступны только из модуля в котором объявлены.
а чем нам мешает эта видимость ?
ну будет видно функцию или переменные в других модулях........ и шо ?

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

Добавлено: Вс сен 15, 2013 20:48:01
ploop
Если у тебя 2-3-5 мегабайт исходников - чердак снесёт придумывать идентификаторы. И всё.

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

Добавлено: Вс сен 15, 2013 21:13:46
blackx
Сокрытие функций и переменных (инкапсуляция, если проводить аналогию из ООП) - это один из способов уменьшить сложность исходного кода. static-переменные и функции в Си позволяют легко разделять код на модули со слабым сопряжением между друг другом. Когда вы читаете код чужого модуля, вы сразу можете определить, какие функции и переменные вам предоставляет этот модуль, а какие использует для своих внутренних целей. Ну и заодно в static-функции можно попрятать все закрытые детали реализации - чтобы конкуренты не прознали ваш хитрый алгоритм ;)

Избавление от коллизий имен - не такая важная задача static-функций и переменных - можно просто сразу использовать идентификаторы вида %имя модуля%_%имя фунции/переменной% при написании программы, и никаких проблем не будет.

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

К слову, часто лучше избавляться от глобальных переменных (extern) вовсе, и писать функции доступа (get_xxx, и только если надо - set_xxx). Помогает контролировать изменения переменных и оставляет возможность поменять логику работы с ними в будущем без перепахивания всего зависимого кода.

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

Добавлено: Вс сен 15, 2013 21:37:07
YS
Если у тебя 2-3-5 мегабайт исходников - чердак снесёт придумывать идентификаторы.
Ага. Рано или поздно придется писать что-то типа

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

void ___my_cool_function_but_not_the_function_I_have_implemented_three_modules_before_but_new_even_cooler_function236738(uint8_t my_new_param)
{
  ...
}
:)))

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

Добавлено: Вс сен 15, 2013 22:11:06
ploop
Избавление от коллизий имен - не такая важная задача static-функций и переменных - можно просто сразу использовать идентификаторы вида %имя модуля%_%имя фунции/переменной% при написании программы, и никаких проблем не будет.
Выше написали пример :)))

На самом деле часто используются функции, имеющие конкретное, короткое имя, и относящиеся именно к модулю. К примеру, есть два модуля "1-wire.c" и "lcd.c". И в первом и во втором есть функции "read()" и "write()". Имена логичны, понятны в контексте модуля. А по вашему, им уже надо выдумывать "read_lcd()" и т.д.

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

Добавлено: Вс сен 15, 2013 22:22:39
shads
Я годик, как на Си залез, тем не менее уже привык глобальные переменные всегда называть именами содержащими указание на модуль...
Например:
Переменная контрольной суммы в библиотеке 1wire называется - OWCheckSumm
Переменные обслуживания 7-ми сегм дисплея - DispLedData[4] и DispLedStrobe
Переменные обработки кнопок - BtnTimeOutCoun, BtnLongAutoVal, BtnFlags
Переменные обслуживания часов DS1307 - BcdClockData [7]
Переменные обслуживания LCD дисплея - LCDUserCharMap [8], LCDBuffer [32]
ну и т.д.
Очень удобно, никаких конфликтов, все интуитивно понятно

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

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

Добавлено: Вс сен 15, 2013 23:16:51
blackx
ploop, ну так и static-переменные не решение этой проблемы, не так ли? Абсолютно нормальная практика писать lcd_read(), one_wire_read() и т. д. А как вы еще в Си хотите?

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

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

Добавлено: Пн сен 16, 2013 00:03:22
ploop
ну так и static-переменные не решение этой проблемы, не так ли?
static-функции.
А static-переменные вещь замечательная, позволяет избавиться от груды глобальных переменных, хотя по сути выполняет их функции.
А как вы еще в Си хотите?
Как в C++: ow.write(); lcd.write(); :)

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

Добавлено: Пн сен 16, 2013 07:55:13
FreshMan
понятно, значит префикс static дает нам всего лишь видимость ф-ции в пределах одного модуля
а эта самая видимость влияет на ресурсы МК, например, память, скорость выполнения и т.д. ?

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

Добавлено: Пн сен 16, 2013 08:34:51
urry
Вот взять бы учебник и бить по голове, пока не дойдет...
статик - это глобальная переменная с ограниченной областью видимости. Все!
Преимущество - конечно, скорость - ее не нужно создавать каждый раз в функции и инициализировать ее можно сразу при создании.
Недостатки - выжирает память, если она создана, то уже никуда не денется, будет висеть в памяти постоянно.

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

Добавлено: Пн сен 16, 2013 09:47:02
ploop
Он про статик-функции спрашивал :)

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

Добавлено: Пн сен 16, 2013 10:10:24
urry

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

Добавлено: Пн сен 16, 2013 10:40:53
FeCat
Допустима ли такая конструкция

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

unsigned char i = 0;

int main(void)
{
  while(1)
  {
  if (i % 4 ==  1)
    {
	......   // Код выполняемый раз в 4 тика i
    }
  i++;
  }
}
При выполнении i++, если i уже равно 255, i станет равным 0, но не произведёт ли при этом микроконтроллер запись ещё и в соседнюю ячейку, или ещё чего не того?

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

Добавлено: Пн сен 16, 2013 11:04:45
coredumped
Зачем использовать static в описании функций.
Поясню на примере - библиотека. Может содержать кучу вспомагательных функций, которые мы не будем выносить в заголовочный файл, короче они для "внутреннего использования". Объявим их static. Если этого не сделать, и отдать эту либу кому нить еще (или самому забыть что находится внутри), то возможен вариант, что кто-то объявит функцию с таким же именем в другом модуле и начнет собирать все вместе, что приведет к поискам граблей. Да, можно называть все эти функции уникальными именами типа sw_driver_lib1_getdata(), но проще и практичней static getd().
Вспомним, про ядро Linux (для примера), которое содержит 100500 драйверов с подобными внутренними функциями. Не заморитесь ли подбирать для них уникальные имена, учитывая, что одних только драйверов Ethernet карт сотни? В МК, конечно по-проще (хотя в моих проектах на ARM - уже нет :)), но стандарт Си расчитан на все случаи - от простеньких программ в одном файле, до ядер ОС содержащих тысячи файлов и сотни тысяч функций.
FeCat писал(а):Допустима ли такая конструкция
При выполнении i++, если i уже равно 255, i станет равным 0, но не произведёт ли при этом микроконтроллер запись ещё и в соседнюю ячейку, или ещё чего не того?
Вполне допустимо, при переполнении переменная обнулится, никакие "соседние данные" не пострадают :)

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

Добавлено: Вт сен 17, 2013 09:22:54
Psych
Круто...а про namespace уже забыли. Спецом же сделанно, чтоб не было коллизий имен.

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

Добавлено: Вт сен 17, 2013 09:55:30
ploop
Да, круто. Только не путайте ANSI С и C++
Первый не поддерживает namespace

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

Добавлено: Вт сен 17, 2013 10:38:20
FreshMan
разрешается ли, при одномодульной программе, но в разных функциях, заводить переменную var с префиксом static ?

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

Добавлено: Вт сен 17, 2013 11:00:37
ploop
Тебе действительно нужна static-переменная? Имей ввиду, это дополнительный расход памяти, т.е. она равнозначна обычной глобальной переменной.

А имена идентификаторов внутри функции имеют область видимости, ограниченную этой функцией. То есть неважно, static- она или нет, любая переменная, объявленная внутри функции, не видна за её пределами.