875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|||||||||||
1 | |||||||||||
Ключевое слово static для переменных в файле18.10.2016, 22:37. Показов 32051. Ответов 24
Метки нет (Все метки)
Много где пишут, если в файле объявить переменную с классом памяти static, то такая переменная будет видна только в том файле где она объявлена. Но на практике так не происходит. Чего я не понимаю?
файл 1
0
|
18.10.2016, 22:37 | |
Ответы с готовыми решениями:
24
Считать из первого файла ключевое слово и цвет и выделить слово во втором файле Подсчитать сколько раз появляется каждое ключевое слово языка С в символьном файле с программой на С Что означает ключевое слово const? Ключевое слово static |
81 / 81 / 33
Регистрация: 03.03.2013
Сообщений: 311
|
|
18.10.2016, 23:05 | 2 |
sys_beginner, на стадии компиляции должен подключаться файл с объявленной переменной ты не правильно понял
Добавлено через 11 минут пардон, то я не так понял Добавлено через 1 минуту sys_beginner, попробуй тоже объявить переменную v в первом файле в вывести значение
0
|
Диссидент
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
|
||||||
18.10.2016, 23:09 | 3 | |||||
sys_beginner, То, что ты написал, абсолютно эквивалентно
Все-таки у меня большое подозрение, что ты возлагаешь на #include какие-то надежды, которые она не оправдывает
1
|
81 / 81 / 33
Регистрация: 03.03.2013
Сообщений: 311
|
|
18.10.2016, 23:09 | 4 |
sys_beginner, Статическая переменная
0
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
18.10.2016, 23:10 [ТС] | 5 |
0
|
81 / 81 / 33
Регистрация: 03.03.2013
Сообщений: 311
|
|
18.10.2016, 23:15 | 6 |
значит она уже об'явлена в подключенном файле
Добавлено через 2 минуты Вспомни, что инклуд просто вставляет содержимое файла в место вызова макрокоманды
0
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
18.10.2016, 23:15 [ТС] | 7 |
Это я понимаю. Но как объяснить утверждение что static переменные видны только в файле в котором они определены?
Ведь переменные которые находятся в файлах которые не включены друг в друга и так не видны Ну да
0
|
81 / 81 / 33
Регистрация: 03.03.2013
Сообщений: 311
|
|
18.10.2016, 23:20 | 8 |
0
|
Диссидент
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
|
|
18.10.2016, 23:29 | 9 |
А! Понял тебя. Экий ты придира!
static int v, объявленный в main.c НЕ ВИДЕН в файле over.c. Сколько и где ни пиши в последнем static int v, или даже extern int v, тот, майновский, будет не виден. Это будет совсем другая переменная. Добавлено через 2 минуты И совершенно неважно, подключишь ты его #includ-ом или напишешь живьем. ЗЫ. Си очень простой язык.
2
|
81 / 81 / 33
Регистрация: 03.03.2013
Сообщений: 311
|
|
18.10.2016, 23:33 | 10 |
0
|
Диссидент
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
|
|
18.10.2016, 23:35 | 11 |
Если они описаны как extern, то очень даже видны. Вот, все функции по умолчанию - extern, и видны, лапушки, видны ото всюду!
Правда, злоупотреблять экстернами умные люди не советуют, но это уж как себя поставишь...
2
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
18.10.2016, 23:45 [ТС] | 12 |
Байт,
Спасибо что пытался донести суть)) Но "дуб" во мне не засыпает. Всё никак не пойму. Поищу потом ещё материалы. Почитаю снова про классы памяти
0
|
19.10.2016, 00:41 | 13 |
Как и многое другое в C, static - перегружен. Этот keyword может использоваться и для указания класса памяти (static vs automatic), и для указания области видимости (global vs local).
Автоматические переменные "живут" на стеке и их время жизни ограничено вызовом функции, а область видимости - телом функции. Статические переменные размещаются в сегменте данных и существуют все время исполнения программы, а их область видимости - от объявления до конца единицы трансляции. Обычно, атрибут static используется, если переменная должна быть в единственном экземпляре и разделяться несколькими функциями. Размещение в сегменте данных делает ее независимой от вызова функции и позволяет нескольким функциям, вызываемым в различные моменты, обмениваться данными между собой (подобно тому, как шпионы используют дупло для передачи донесений). Не по теме: Аналогичный механизм использует OS - объекты ядра (file, mutex etc) "статичны" по отношению к программам пользователя и позволяют им взаимодействовать между собой. Часто функции объявляют как static, чтобы перекрыть дефолтную видимость (external) и сделать недоступными за пределами модуля. В частности, в разных единицах трансляции можно иметь различные функции с тем же самым именем. Static: Многоцелевое ключевое слово
2
|
Вездепух
11694 / 6373 / 1724
Регистрация: 18.10.2014
Сообщений: 16,066
|
||||||
19.10.2016, 00:45 | 14 | |||||
Сообщение было отмечено Undisputed как решение
Решение
Не в файле, а в единице трансляции. Единицей трансляции называется уже обработанный препроцессором исходный файл, т.е. файл с уже полностью подставленными в него всеми #include-файлами, полностью подставленным макросами и т.п.
В исходном примере единица трансляции будет выглядеть примерно так
v , как и обещали.
1
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|||||||||||
19.10.2016, 10:22 [ТС] | 15 | ||||||||||
gazlan,
Спасибо. Я читал информацию по той ссылке. Там именно написано файл, а не единица трансляции. В этом и была загвоздка. TheCalligrapher,
two + one + stdio = 1 единица трансляции three + two + one + stdio = 1 единица трансляции Я правильно понимаю? Если так, то учитывая, что файлы one и two попадают в разные единицы трансляции которые компилируются отдельно, это приводит к дублированию исходного кода. Исходный код ведь в память загружается в момент запуска программы? Выходит, такая ситуация приводит к оверхеду. Как с этим бороться? Добавлено через 10 минут Как вариант использовать условную компиляцию, может есть другие, более правильные способы?
Но в таком случае интересно, как получить доступ к уже скомпилированному коду который не будет включен через include за счет условной компиляции. только через extern? Как в таких ситуациях поступать? Хочется знать как обычно делают опытные разработчики
0
|
19.10.2016, 17:27 | 16 | |||||
Следует учитывать, что до компиляции работает препроцессор (в ранних версиях компиляторов это была отдельная программа). В частности, он обрабатывает все директивы #include, превращая дерево включений в единицу трансляции.
Но, от того, что вы N раз напишете
IMHO, стоит избегать "каскадного" включения заголовочных файлов (одного в другой) - это приводит к тяжелым рекурсивным зависимостям. Иными словами, я предпочитаю в каждом C/C++ файле иметь список только реально необходимых в нем H-файлов. Модификатор extern обычно, появляется либо как следствие продуманной оптимизации, либо как результат неверного дизайна. Для межмодульного азаимодействия есть функции, общие переменные часто ведут к тяжелым труднообнаруживаемым ошибкам.
1
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
19.10.2016, 17:47 [ТС] | 17 |
А реализацию .h файла включаете в сам .h файл с помощью #include?
А где можно узнать как делать правильно? Желательно с обноснованием точки зрения То есть если 2 единицы трансляции используют один и тот же файл, в конечном счете дубликат кода удаляется и используется один экземпляр? Раз уж мы заговорили о правильности. То как быть в случаях, когда нужна функция printf, но из за одной функции приходится подключать весь stdio. Как избавиться от лишних функций?
0
|
19.10.2016, 18:14 | 19 |
Не понял вопроса. В H-файле размещаются описания, кода в них нет. Реализация выносится в C/C++. Это позволяет разделить интерфейс и реализацию. Тому кто использует функцию важно знать детали контракта (количество и типы параметров, тип возвращаемого значения), но не детали реализации (более того, они должны быть преднамеренно скрыты).
1
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
19.10.2016, 18:45 [ТС] | 20 |
gazlan,
Спасибо, вы очень помогли! Только не понятно одно Выглядит привлекательно. Но откуда компилятор узнает про .с файл(реализацию интерфейса) если его не включать в код программы явно? Допустим нахожусь в директории где расположены файлы программы. Компилятор запускаю из командной строки с помощью вызова сс указав один или несколько файлов для компиляции(есть ли команда что бы компилировался весь код из директории рекурсивно?). Или через Visual Studio Добавлено через 30 секунд Байт, Не
0
|
19.10.2016, 18:45 | |
19.10.2016, 18:45 | |
Помогаю со студенческими работами здесь
20
Зачем использовать ключевое слово static? Ключевое слово static в объявлении функции Зачем и когда нужно писать ключевое слово static Классы.Ключевое слово static - выдает ошибку "неразрешенный внешний символ" Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |