Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.90/29: Рейтинг темы: голосов - 29, средняя оценка - 4.90
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700

Ключевое слово extern

21.03.2016, 14:09. Показов 6461. Ответов 42
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть код в файле file1.cpp

C++
1
2
3
4
5
6
7
8
9
10
#include "stdafx.h"
#include <iostream>
#include <string>
#include "file2.cpp"
 
int main()
{
    cout << "VAR FROM file2.cpp " << varFromFunctions << endl;
    return 0;
}
И код во включаемом файле file2.cpp
C++
1
std::string varFromFunctions = "VALUE OF VAR FROM FILE file2.cpp";
Почему в первом файле в функции main выражение cout << "VAR FROM functions.cpp " << varFromFunctions << endl;
выводит значение переменной varFromFunctions которая определена в файле file2.cpp? Читал что переменные в отличии от функций имеют локальную область видимости и по умолчанию доступны только в том файле в котором они определены. Что бы переменные были доступны глобально(в данном случае в переменная из file2.cpp в file1.cpp)
нужно её определить с помощью ключевого слова extern. Вопрос в том, почему без extern все работает? Зачем тогда нужно это ключевое слово если и без него все работает?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.03.2016, 14:09
Ответы с готовыми решениями:

Ключевое слово extern
Взято отсюда: Теперь вопрос: почему так делать нельзя? Я написал программу, она имеет вид: extern int x; int main() { ...

Определить, в введенном предложении слово, которое состоит из тех же букв, что и заданное ключевое слово.
Ввести предложения и ключевое слово. Определить, в введенном предложении слово, которое состоит из тех же букв, что и заданное ключевое...

Ключевое слово this
Можно какой-нибудь простой пример, чтобы понять зачем это нужно?

42
 Аватар для iars
6 / 6 / 7
Регистрация: 19.03.2016
Сообщений: 50
21.03.2016, 14:14
sys_beginner, сработало потому, что вы включили cpp-файл. Этого делать нельзя, используйте extern.

Не по теме:

Я удивлён, что на вас не выругался компоновщик. Должен, по идее.

0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
21.03.2016, 14:19  [ТС]
iars,
Почему не следует включать файл? Включение файлов разве происходит автоматически?
Когда не включаю - не работает. Тогда ругается(не знаю компоновщик ли ругается) но указывает на файл с расширением .obj а когда есть #include тогда все ок
0
 Аватар для iars
6 / 6 / 7
Регистрация: 19.03.2016
Сообщений: 50
21.03.2016, 14:24
sys_beginner, не происходит. Они компилируются отдельно и линкуются в один исполняемый. Если у вас будет так:
Кликните здесь для просмотра всего текста
source1.cpp
C++
1
2
3
4
5
6
7
#include <iostream>
#include "source2.cpp"
 
int main() {
    my_function();
    return 0;
}
source2.cpp
C++
1
2
3
void my_function() {
    // ...
}

то, фактически, получится, что у вас определена функция my_function в обоих файлах. И это не скомпилируется (хотя, может быть, скомпилируется, но точно не слинкуется).
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
21.03.2016, 14:25
Цитата Сообщение от iars Посмотреть сообщение
Этого делать нельзя,
Не то что нельзя. Не принято. Но понимать смысл директивы #include безусловно, необходимо. А вот этого понимания, имхо, у ТС нет.
0
 Аватар для iars
6 / 6 / 7
Регистрация: 19.03.2016
Сообщений: 50
21.03.2016, 14:29
extern же как раз нужен, чтобы таскать глобальные переменные между файлами. То есть:
header.h
C++
1
2
3
4
5
6
7
#ifndef HEADER_H
#define HEADER_H
 
extern int global_var; // любой файл, включающий header.h, сможет использовать эту переменную
void print_global_var();
 
#endif
source1.cpp
C++
1
2
3
4
5
6
#include "header.h"
 
int main() {
    global_var = 5;
    print_global_var();
}
source2.cpp
C++
1
2
3
4
5
6
7
#include "header.h"
 
int global_var = 3;
 
void print_global_var() {
    printf("%d\n", global_var);
}

Не по теме:

а вообще всё это наследие си и процедурный подход, а потому - зло. :genius:

0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
21.03.2016, 14:30  [ТС]
iars,
В вашем примере же нету двойного определения. Там определение в source2.cpp а в source1.cpp
вызов функции my_function. Не вижу повода для ошибок
Пост: Ключевое слово extern

Цитата Сообщение от Байт Посмотреть сообщение
Но понимать смысл директивы #include безусловно, необходимо
Я понимаю, то есть код из одного файла как бы "вставляется" в тот в который он подключен.
Но вопрос был в другом. Я читал что переменные не "вставляются" из одного файла в другой по умолчанию и что бы это разрешить нужно использовать extern. Но и без него все работает прекрасно а вот без #include выводит ошибку не компилируется
0
 Аватар для iars
6 / 6 / 7
Регистрация: 19.03.2016
Сообщений: 50
21.03.2016, 14:33
sys_beginner, в моём примере оно как раз есть, потому что я включаю содержимое одного файла, содержащего определение функции, в другой. при этом оба этих файла будут компилироваться и отправятся в компоновщик, который и выдаст ошибку.
Цитата Сообщение от sys_beginner Посмотреть сообщение
Но и без него все работает прекрасно
это в вашем конкретном случае работает прекрасно, потому что вы включили файл с кодом, чего делать не следует. если уберёте - не будет работать.
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
21.03.2016, 14:41
Цитата Сообщение от sys_beginner Посмотреть сообщение
Я понимаю, то есть код из одного файла как бы "вставляется" в тот в который он подключен.
А если понимаете, то в чем собственно вопрос? И при чем здесь "как бы"?

Добавлено через 4 минуты
Ваша строка в file2.cpp
C++
1
std::string varFromFunctions = "VALUE OF VAR FROM FILE file2.cpp";
расположена вне функций? Очевидно, что вне, иначе бы не сработало. А все, что объявлено вне функции, становится видно во всех нижележащих функциях. В этом файле. Но файл-то у вас один!
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
21.03.2016, 16:00  [ТС]
Я слегка запутался.
iars,
Вы говорите, что include использовать не нужно, а надо через extern. Но в примере Ключевое слово extern используете extern вместе с #include. Это противоречие или я чего то не понял? И как без #include можно использовать код одного файла в другом раз уж #include это плохо а без него ничего не работает?

Цитата Сообщение от Байт Посмотреть сообщение
Очевидно, что вне, иначе бы не сработало. А все, что объявлено вне функции, становится видно во всех нижележащих функциях.
Да, но я читал, что в случае подключаемых файлов, все переменные из внешнего файла не доступны, если их явно не определить как extern. А на деле они доступны и без extern, отсюда недопонимание.

Меня обманули в статье или я чего то не понимаю? Прошу объяснить
0
 Аватар для iars
6 / 6 / 7
Регистрация: 19.03.2016
Сообщений: 50
21.03.2016, 16:08
sys_beginner, я говорю, что #include для cpp-файлов использовать не нужно. читайте внимательно. пример с тем, как нужно, я уже привёл. вот он.
переменные из cpp-файлов, не определённые как extern, недоступны.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
21.03.2016, 16:36  [ТС]
Цитата Сообщение от iars Посмотреть сообщение
переменные из cpp-файлов, не определённые как extern, недоступны
Доступны, об этом и речь. Пользуюсь Visual Studio 2015 Community.
Насколько мне известно расширение файла не имеет значение, они лишь делают файловую структуру более наглядной.
в .h описания, в .cpp определения. Разве нет?
0
 Аватар для iars
6 / 6 / 7
Регистрация: 19.03.2016
Сообщений: 50
21.03.2016, 17:02
sys_beginner, если вы будете включать cpp-файлы с определениями с помощью include, у вас будут ошибки компоновки. такие, как на картинке. потому что cpp-файлы, в отличие от заголовков, компилируются и соединяются компоновщиком в исполняемый.
Миниатюры
Ключевое слово extern  
1
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
21.03.2016, 17:08
Цитата Сообщение от sys_beginner Посмотреть сообщение
Насколько мне известно расширение файла не имеет значение, они лишь делают файловую структуру более наглядной.
Теоретически - да. Практически - нет.
По умолчанию, в VS cpp - компилируются, h - нет. (Откройте свойства файлов и посмотрите)
Теперь по порядку. #include относится к препроцессору, а extern к языку.
Есть такое понятие: единица трансляции - это файл исходного кода после препроцессора (читай после раскрытия всех #include). Т.е. если написать в some.cpp #include "other.cpp" - по умолчанию other.cpp скомпилируется два раза - самостоятельно и как часть some.cpp. В результате имеем проблемы на этапе линковки, и, в приличном обществе, за включение .cpp отрывают руки.
С помощью extern вы вносите в область видимости переменную из другой единицы трансляции.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
21.03.2016, 17:09  [ТС]
iars,
У меня таких проблем не возникает...

Цитата Сообщение от iars Посмотреть сообщение
если вы будете включать cpp-файлы с определениями с помощью include, у вас будут ошибки компоновки.
Судя по всему у вас настроен некий авто include и при явном include происходит повторное определение, что приводит к ошибкам. У меня без явного include не получается сделать билд.

Например, если в файле a.cpp вызываю функцию определенную в файле b.cpp без явного include b.cpp в a.cpp, билд сделать не получится. А у вас, судя по всему, так можно.
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
21.03.2016, 17:11
Цитата Сообщение от sys_beginner Посмотреть сообщение
Например, если в файле a.cpp вызываю функцию определенную в файле b.cpp без явного include b.cpp в a.cpp, билд сделать не получится.
Прототип функции - не, не слышал.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
21.03.2016, 17:12  [ТС]
Цитата Сообщение от avgoor Посмотреть сообщение
В результате имеем проблемы на этапе линковки
Какие проблемы? У меня все работает. Наоборот без include не работает
0
 Аватар для iars
6 / 6 / 7
Регистрация: 19.03.2016
Сообщений: 50
21.03.2016, 17:15
sys_beginner, потому что функций у вас в cpp-файле нет, потому и работает. вам уже как минимум три раза об этом сказали.
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
21.03.2016, 17:17
Цитата Сообщение от sys_beginner Посмотреть сообщение
У меня все работает. Наоборот без include не работает
Что не работает/работает?
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
21.03.2016, 17:18  [ТС]
Цитата Сообщение от iars Посмотреть сообщение
потому что функций у вас в cpp-файле нет, потому и работает. вам уже как минимум три раза об этом сказали.
Каких функций? В каком файле? Вообще я спрашивал про переменные а не функции
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.03.2016, 17:18
Помогаю со студенческими работами здесь

Ключевое слово this
В данный момент читаю книгу по Java, но и по С++ это тоже встречалось, хотя описание было не сильно понятно. Вопрос следующий, что делает...

Ключевое слово try
Вот вчера печатал программу и нечаяно поставил вместо слова tru слово try и оно выделелось жырным шрифтом.А в моем компиляторе все ключевые...

Ключевое слово break
Как правильно надо использовать ключевое слово break??

Ключевое слово static_cast
Чё это такое?Зачем оно нужно?

Ключевое слово export
В стандарте C++ встречается ключевое слово export, если кому-то приходилось реально использовать его в коде, то приведите пожалуйста пример...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru