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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

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

Сообщение FreshMan »

и что нам это дает ?
Tell Me The Truth
Реклама
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

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

Сообщение ploop »

(константы, переменные итп) - если их объявить static, они будут видны/доступны только из модуля в котором объявлены.
Один важный момент: static-переменные, объявленные локально, не теряют своего значения при выходе из функции.
Реклама
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

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

Сообщение FreshMan »

coredumped писал(а):
FreshMan писал(а):в каких случаях перед названием ф-ции ставится префикс static ?
Если нужно ограничить видимость имени этой ф-ции модулем, в котором она объявлена. Это касается любых глобальных идентификаторов (константы, переменные итп) - если их объявить static, они будут видны/доступны только из модуля в котором объявлены.
а чем нам мешает эта видимость ?
ну будет видно функцию или переменные в других модулях........ и шо ?
Tell Me The Truth
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

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

Сообщение ploop »

Если у тебя 2-3-5 мегабайт исходников - чердак снесёт придумывать идентификаторы. И всё.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
blackx
Говорящий с текстолитом
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

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

Сообщение blackx »

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

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

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

К слову, часто лучше избавляться от глобальных переменных (extern) вовсе, и писать функции доступа (get_xxx, и только если надо - set_xxx). Помогает контролировать изменения переменных и оставляет возможность поменять логику работы с ними в будущем без перепахивания всего зависимого кода.
Изображение only pure true norwegian blackx Изображение
Реклама
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

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

Сообщение 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)
{
  ...
}
:)))
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Реклама
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

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

Сообщение ploop »

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

На самом деле часто используются функции, имеющие конкретное, короткое имя, и относящиеся именно к модулю. К примеру, есть два модуля "1-wire.c" и "lcd.c". И в первом и во втором есть функции "read()" и "write()". Имена логичны, понятны в контексте модуля. А по вашему, им уже надо выдумывать "read_lcd()" и т.д.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

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

Мало того, в основном теле программы стараюсь вообще не работать с переменными модулей... стараюсь в самих модулях написать все необходимые функции работы с этими переменными... и из основного тела программы работаю только с этими функциями (хотя функциями они являются чисто теоритически... т.к. скорее всего их код зачастую просто вставляется в основной код из за их малого размера)
Аватара пользователя
blackx
Говорящий с текстолитом
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

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

Сообщение blackx »

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

А излишне длинные имена, как написали выше, всегда получаются из-за требований к кодированию. Ни один нормальный человек не будет такое специально выдумывать.
Изображение only pure true norwegian blackx Изображение
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

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

Сообщение ploop »

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

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

Сообщение FreshMan »

понятно, значит префикс static дает нам всего лишь видимость ф-ции в пределах одного модуля
а эта самая видимость влияет на ресурсы МК, например, память, скорость выполнения и т.д. ?
Tell Me The Truth
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

Вот взять бы учебник и бить по голове, пока не дойдет...
статик - это глобальная переменная с ограниченной областью видимости. Все!
Преимущество - конечно, скорость - ее не нужно создавать каждый раз в функции и инициализировать ее можно сразу при создании.
Недостатки - выжирает память, если она создана, то уже никуда не денется, будет висеть в памяти постоянно.
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

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

Сообщение ploop »

Он про статик-функции спрашивал :)
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

Аватара пользователя
FeCat
Прорезались зубы
Сообщения: 211
Зарегистрирован: Пт окт 21, 2011 14:39:31

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

Сообщение FeCat »

Допустима ли такая конструкция

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

unsigned char i = 0;

int main(void)
{
  while(1)
  {
  if (i % 4 ==  1)
    {
	......   // Код выполняемый раз в 4 тика i
    }
  i++;
  }
}
При выполнении i++, если i уже равно 255, i станет равным 0, но не произведёт ли при этом микроконтроллер запись ещё и в соседнюю ячейку, или ещё чего не того?
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

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

Сообщение coredumped »

Зачем использовать static в описании функций.
Поясню на примере - библиотека. Может содержать кучу вспомагательных функций, которые мы не будем выносить в заголовочный файл, короче они для "внутреннего использования". Объявим их static. Если этого не сделать, и отдать эту либу кому нить еще (или самому забыть что находится внутри), то возможен вариант, что кто-то объявит функцию с таким же именем в другом модуле и начнет собирать все вместе, что приведет к поискам граблей. Да, можно называть все эти функции уникальными именами типа sw_driver_lib1_getdata(), но проще и практичней static getd().
Вспомним, про ядро Linux (для примера), которое содержит 100500 драйверов с подобными внутренними функциями. Не заморитесь ли подбирать для них уникальные имена, учитывая, что одних только драйверов Ethernet карт сотни? В МК, конечно по-проще (хотя в моих проектах на ARM - уже нет :)), но стандарт Си расчитан на все случаи - от простеньких программ в одном файле, до ядер ОС содержащих тысячи файлов и сотни тысяч функций.
FeCat писал(а):Допустима ли такая конструкция
При выполнении i++, если i уже равно 255, i станет равным 0, но не произведёт ли при этом микроконтроллер запись ещё и в соседнюю ячейку, или ещё чего не того?
Вполне допустимо, при переполнении переменная обнулится, никакие "соседние данные" не пострадают :)
Последний раз редактировалось Gudd-Head Пн сен 16, 2013 11:51:09, всего редактировалось 1 раз.
Причина: Склеил
Все будет только лучше, в крайнем случае - хуже.
Аватара пользователя
Psych
Опытный кот
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

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

Сообщение Psych »

Круто...а про namespace уже забыли. Спецом же сделанно, чтоб не было коллизий имен.
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

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

Сообщение ploop »

Да, круто. Только не путайте ANSI С и C++
Первый не поддерживает namespace
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

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

Сообщение FreshMan »

разрешается ли, при одномодульной программе, но в разных функциях, заводить переменную var с префиксом static ?
Tell Me The Truth
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

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

Сообщение ploop »

Тебе действительно нужна static-переменная? Имей ввиду, это дополнительный расход памяти, т.е. она равнозначна обычной глобальной переменной.

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

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