Вопросы по С/С++ (СИ)
- Реклама
Re: Вопросы по С/С++ (СИ)
Один важный момент: static-переменные, объявленные локально, не теряют своего значения при выходе из функции.(константы, переменные итп) - если их объявить static, они будут видны/доступны только из модуля в котором объявлены.
Re: Вопросы по С/С++ (СИ)
а чем нам мешает эта видимость ?coredumped писал(а):Если нужно ограничить видимость имени этой ф-ции модулем, в котором она объявлена. Это касается любых глобальных идентификаторов (константы, переменные итп) - если их объявить static, они будут видны/доступны только из модуля в котором объявлены.FreshMan писал(а):в каких случаях перед названием ф-ции ставится префикс static ?
ну будет видно функцию или переменные в других модулях........ и шо ?
Tell Me The Truth
Re: Вопросы по С/С++ (СИ)
Если у тебя 2-3-5 мегабайт исходников - чердак снесёт придумывать идентификаторы. И всё.
- blackx
- Говорящий с текстолитом
- Сообщения: 1518
- Зарегистрирован: Пт дек 28, 2012 21:56:46
- Откуда: St. Petersburg
Re: Вопросы по С/С++ (СИ)
Сокрытие функций и переменных (инкапсуляция, если проводить аналогию из ООП) - это один из способов уменьшить сложность исходного кода. static-переменные и функции в Си позволяют легко разделять код на модули со слабым сопряжением между друг другом. Когда вы читаете код чужого модуля, вы сразу можете определить, какие функции и переменные вам предоставляет этот модуль, а какие использует для своих внутренних целей. Ну и заодно в static-функции можно попрятать все закрытые детали реализации - чтобы конкуренты не прознали ваш хитрый алгоритм 
Избавление от коллизий имен - не такая важная задача static-функций и переменных - можно просто сразу использовать идентификаторы вида %имя модуля%_%имя фунции/переменной% при написании программы, и никаких проблем не будет.
Преимущества такого подхода могут быть незаметны в небольших программных проектах, но в крупных инкапсуляция очень помогает сохранять код простым и понятным. Чем меньше время жизни и область видимости переменной - тем лучше.
К слову, часто лучше избавляться от глобальных переменных (extern) вовсе, и писать функции доступа (get_xxx, и только если надо - set_xxx). Помогает контролировать изменения переменных и оставляет возможность поменять логику работы с ними в будущем без перепахивания всего зависимого кода.
Избавление от коллизий имен - не такая важная задача static-функций и переменных - можно просто сразу использовать идентификаторы вида %имя модуля%_%имя фунции/переменной% при написании программы, и никаких проблем не будет.
Преимущества такого подхода могут быть незаметны в небольших программных проектах, но в крупных инкапсуляция очень помогает сохранять код простым и понятным. Чем меньше время жизни и область видимости переменной - тем лучше.
К слову, часто лучше избавляться от глобальных переменных (extern) вовсе, и писать функции доступа (get_xxx, и только если надо - set_xxx). Помогает контролировать изменения переменных и оставляет возможность поменять логику работы с ними в будущем без перепахивания всего зависимого кода.
only pure true norwegian blackx 
- Реклама
Re: Вопросы по С/С++ (СИ)
Ага. Рано или поздно придется писать что-то типаЕсли у тебя 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: Вопросы по С/С++ (СИ)
Выше написали примерИзбавление от коллизий имен - не такая важная задача static-функций и переменных - можно просто сразу использовать идентификаторы вида %имя модуля%_%имя фунции/переменной% при написании программы, и никаких проблем не будет.
На самом деле часто используются функции, имеющие конкретное, короткое имя, и относящиеся именно к модулю. К примеру, есть два модуля "1-wire.c" и "lcd.c". И в первом и во втором есть функции "read()" и "write()". Имена логичны, понятны в контексте модуля. А по вашему, им уже надо выдумывать "read_lcd()" и т.д.
Re: Вопросы по С/С++ (СИ)
Я годик, как на Си залез, тем не менее уже привык глобальные переменные всегда называть именами содержащими указание на модуль...
Например:
Переменная контрольной суммы в библиотеке 1wire называется - OWCheckSumm
Переменные обслуживания 7-ми сегм дисплея - DispLedData[4] и DispLedStrobe
Переменные обработки кнопок - BtnTimeOutCoun, BtnLongAutoVal, BtnFlags
Переменные обслуживания часов DS1307 - BcdClockData [7]
Переменные обслуживания LCD дисплея - LCDUserCharMap [8], LCDBuffer [32]
ну и т.д.
Очень удобно, никаких конфликтов, все интуитивно понятно
Мало того, в основном теле программы стараюсь вообще не работать с переменными модулей... стараюсь в самих модулях написать все необходимые функции работы с этими переменными... и из основного тела программы работаю только с этими функциями (хотя функциями они являются чисто теоритически... т.к. скорее всего их код зачастую просто вставляется в основной код из за их малого размера)
Например:
Переменная контрольной суммы в библиотеке 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: Вопросы по С/С++ (СИ)
ploop, ну так и static-переменные не решение этой проблемы, не так ли? Абсолютно нормальная практика писать lcd_read(), one_wire_read() и т. д. А как вы еще в Си хотите?
А излишне длинные имена, как написали выше, всегда получаются из-за требований к кодированию. Ни один нормальный человек не будет такое специально выдумывать.
А излишне длинные имена, как написали выше, всегда получаются из-за требований к кодированию. Ни один нормальный человек не будет такое специально выдумывать.
only pure true norwegian blackx 
Re: Вопросы по С/С++ (СИ)
static-функции.ну так и static-переменные не решение этой проблемы, не так ли?
А static-переменные вещь замечательная, позволяет избавиться от груды глобальных переменных, хотя по сути выполняет их функции.
Как в C++: ow.write(); lcd.write();А как вы еще в Си хотите?
Re: Вопросы по С/С++ (СИ)
понятно, значит префикс static дает нам всего лишь видимость ф-ции в пределах одного модуля
а эта самая видимость влияет на ресурсы МК, например, память, скорость выполнения и т.д. ?
а эта самая видимость влияет на ресурсы МК, например, память, скорость выполнения и т.д. ?
Tell Me The Truth
- urry
- Сверлит текстолит когтями
- Сообщения: 1262
- Зарегистрирован: Пн дек 08, 2008 10:58:48
- Откуда: Винница
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Вот взять бы учебник и бить по голове, пока не дойдет...
статик - это глобальная переменная с ограниченной областью видимости. Все!
Преимущество - конечно, скорость - ее не нужно создавать каждый раз в функции и инициализировать ее можно сразу при создании.
Недостатки - выжирает память, если она создана, то уже никуда не денется, будет висеть в памяти постоянно.
статик - это глобальная переменная с ограниченной областью видимости. Все!
Преимущество - конечно, скорость - ее не нужно создавать каждый раз в функции и инициализировать ее можно сразу при создании.
Недостатки - выжирает память, если она создана, то уже никуда не денется, будет висеть в памяти постоянно.
Re: Вопросы по С/С++ (СИ)
Он про статик-функции спрашивал 
Re: Вопросы по С/С++ (СИ)
Допустима ли такая конструкция
При выполнении i++, если i уже равно 255, i станет равным 0, но не произведёт ли при этом микроконтроллер запись ещё и в соседнюю ячейку, или ещё чего не того?
Код: Выделить всё
unsigned char i = 0;
int main(void)
{
while(1)
{
if (i % 4 == 1)
{
...... // Код выполняемый раз в 4 тика i
}
i++;
}
}- coredumped
- Опытный кот
- Сообщения: 838
- Зарегистрирован: Вт апр 12, 2011 18:38:19
- Откуда: с Земли
Re: Вопросы по С/С++ (СИ)
Зачем использовать static в описании функций.
Поясню на примере - библиотека. Может содержать кучу вспомагательных функций, которые мы не будем выносить в заголовочный файл, короче они для "внутреннего использования". Объявим их static. Если этого не сделать, и отдать эту либу кому нить еще (или самому забыть что находится внутри), то возможен вариант, что кто-то объявит функцию с таким же именем в другом модуле и начнет собирать все вместе, что приведет к поискам граблей. Да, можно называть все эти функции уникальными именами типа sw_driver_lib1_getdata(), но проще и практичней static getd().
Вспомним, про ядро Linux (для примера), которое содержит 100500 драйверов с подобными внутренними функциями. Не заморитесь ли подбирать для них уникальные имена, учитывая, что одних только драйверов Ethernet карт сотни? В МК, конечно по-проще (хотя в моих проектах на ARM - уже нет
, но стандарт Си расчитан на все случаи - от простеньких программ в одном файле, до ядер ОС содержащих тысячи файлов и сотни тысяч функций.

Поясню на примере - библиотека. Может содержать кучу вспомагательных функций, которые мы не будем выносить в заголовочный файл, короче они для "внутреннего использования". Объявим их 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 раз.
Причина: Склеил
Причина: Склеил
Все будет только лучше, в крайнем случае - хуже.
Re: Вопросы по С/С++ (СИ)
Круто...а про namespace уже забыли. Спецом же сделанно, чтоб не было коллизий имен.
Re: Вопросы по С/С++ (СИ)
Да, круто. Только не путайте ANSI С и C++
Первый не поддерживает namespace
Первый не поддерживает namespace
Re: Вопросы по С/С++ (СИ)
разрешается ли, при одномодульной программе, но в разных функциях, заводить переменную var с префиксом static ?
Tell Me The Truth
Re: Вопросы по С/С++ (СИ)
Тебе действительно нужна static-переменная? Имей ввиду, это дополнительный расход памяти, т.е. она равнозначна обычной глобальной переменной.
А имена идентификаторов внутри функции имеют область видимости, ограниченную этой функцией. То есть неважно, static- она или нет, любая переменная, объявленная внутри функции, не видна за её пределами.
А имена идентификаторов внутри функции имеют область видимости, ограниченную этой функцией. То есть неважно, static- она или нет, любая переменная, объявленная внутри функции, не видна за её пределами.


