Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.65
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
#1

Как в include отделить интерфейс от реализации? - C++

20.08.2011, 10:38. Просмотров 2200. Ответов 13

В Turbo Pascal можно подключать модули, которые содержат разделы implementation и interface. Так содержимое раздела интерфейса доступно в программе, к которой подключается модуль, а всё остальное - нет. Как сделать аналогично на C?

Т.е. надо написать заголовочный файл с функцией, напр. int a(int x, int y) { return sum(x,y); }, но функция sum д.б. не видна в программе, к которой подключается заголовочный файл.

Или - как в include файле оставить только прототипы функций, а их реализации вынести в другой файл.

Собственно вопрос, скорее - как оформлять/делать модули на C.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.08.2011, 10:38     Как в include отделить интерфейс от реализации?
Посмотрите здесь:
C++ Отделить описание шаблонных функций и классов от реализации
C++ Работа с файлами в C# с исп. библиотек #include <stdio.h> #include <stdlib.h> #include <math.h> #include <io.h>
C++ Интерфейс и реализации
C++ #include<iostream>// подключение библиотек #include <conio.h> #include <climits>
Чем отличается #include <cstring>, #include <string> и #include <string.h>? C++
ошибка в лабе не находит #include<iomanip.h> #include<conio.h> C++
Как отделить поток с помощью detach? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
20.08.2011, 15:49     Как в include отделить интерфейс от реализации? #2
Цитата Сообщение от skvor Посмотреть сообщение
как в include файле оставить только прототипы функций, а их реализации вынести в другой файл.
Так и делать.

module.h
C
1
2
3
4
5
6
#ifndef MODULE_NAME_H
#define MODULE_NAME_H
 
int foo();
 
#endif
module.c
C
1
2
3
4
5
6
#include "module.h"
 
int foo() {
    /* some code */
    return 0;
}
main.c
C
1
2
3
4
5
6
7
#include <stdio.h>
#include "module.h"
 
int main() {
    printf("%d\n", foo());
    return 0;
}
accept
4820 / 3240 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
21.08.2011, 07:14     Как в include отделить интерфейс от реализации? #3
в module.c не надо подключать module.h
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
21.08.2011, 10:40  [ТС]     Как в include отделить интерфейс от реализации? #4
Цитата Сообщение от fasked Посмотреть сообщение
Так и делать.
Таки сделалл
/var/tmp//cc3WaiFc.o(.text+0x12): In function `main':
: undefined reference to `foo'
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
21.08.2011, 10:45     Как в include отделить интерфейс от реализации? #5
main.c нужно линковать с module.c

Добавлено через 2 минуты
Цитата Сообщение от accept Посмотреть сообщение
в module.c не надо подключать module.h
лучше подключать.
ибо если он случайно опишет декларации для foo() в .c и .h по разному, он хоть получит внятное сообщение о том, что перегрузки в Си не существует. иначе получит анрезолвед.

Добавлено через 1 минуту
Цитата Сообщение от skvor Посмотреть сообщение
undefined reference to `foo'
показывай как компилишь.
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
21.08.2011, 10:47  [ТС]     Как в include отделить интерфейс от реализации? #6
Цитата Сообщение от niXman Посмотреть сообщение
main.c нужно линковать с module.c
К сожалению, не могу найти внятное описание этого по-русски.

Добавлено через 1 минуту
Цитата Сообщение от niXman Посмотреть сообщение
показывай как компилишь.
Как обычную программу из одного файла с include-ами.
gcc test.c -o./test
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
21.08.2011, 11:09     Как в include отделить интерфейс от реализации? #7
Цитата Сообщение от skvor Посмотреть сообщение
Как обычную программу из одного файла с include-ами.
А надо:
Код
gcc test.c module.c -o test
То есть перечислить надо каждый *.с файл.
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
21.08.2011, 11:10     Как в include отделить интерфейс от реализации? #8
компилить так:
gcc -c module.c
gcc -c main.c
gcc module.o main.o -omain
или так:

gcc module.c main.c -omain
Добавлено через 23 секунды
опоздал
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
21.08.2011, 12:33  [ТС]     Как в include отделить интерфейс от реализации? #9
Спасибо, работает, но утеряно понимание include и смысла заголовочного файла.
test.c
C
1
2
3
4
5
6
7
#include <stdio.h>
//#include "module.h" //<-!! №1 выключил, а оно всё равно компилируется
 
int main() {
  printf("%d\n", a());
  return 0;
}
module.h
C
1
2
3
4
5
6
#ifndef MODULE_NAME_H //<-- №2 А зачем?
#define MODULE_NAME_H
 
int a();
 
#endif
module.c
C
1
2
3
4
5
6
//#include "module.h" //<-- №3 работает и без него + а зачем писать?
 
int c() { return 666; } // <-- №4 как сделать, что б после линковки
       // кода от функции c() не было, т.к. нет фактических вызовов?
int b() { return 5; }
int a() { return 2+b(); }
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
21.08.2011, 12:57     Как в include отделить интерфейс от реализации? #10
Цитата Сообщение от skvor Посмотреть сообщение
№1 выключил, а оно всё равно компилируется
В Си бардак с этим делом
Цитата Сообщение от skvor Посмотреть сообщение
А зачем?
Чтобы один заголовочный файл не подставлялся несколько раз. Директива #include это команда препроцессора. Грубо говоря, препроцессор, встречая #include, просто вставляет содержимое файла в это место. Так вот если один файл будет подставлен несколько раз, то возможно наличие повторного объявления функции или переменной, что приведет к ошибке компиляции. С наличием подобных макросов файл будет подставлен только один раз в одной единице трансляции.
Цитата Сообщение от skvor Посмотреть сообщение
№3 работает и без него + а зачем писать?
Ответ был выше.
Цитата Сообщение от niXman Посмотреть сообщение
лучше подключать.
ибо если он случайно опишет декларации для foo() в .c и .h по разному, он хоть получит внятное сообщение о том, что перегрузки в Си не существует. иначе получит анрезолвед.
Цитата Сообщение от skvor Посмотреть сообщение
№4 как сделать, что б после линковки кода от функции c() не было, т.к. нет фактических вызовов?
Я не уверен, что он будет в конечном исполняемом файле
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
21.08.2011, 13:34  [ТС]     Как в include отделить интерфейс от реализации? #11
Цитата Сообщение от fasked Посмотреть сообщение
Я не уверен, что он будет в конечном исполняемом файле
Не-а, у меня получается 4875 байт если функция c() есть в module.c, и 4841 если её закоментировать.
Я так понимаю, надо отдельно разбираться с линковщиком, стандартные библиотеки, они же не запихивают всё что в них есть.
accept
4820 / 3240 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
22.08.2011, 02:28     Как в include отделить интерфейс от реализации? #12
Цитата Сообщение от niXman
ибо если он случайно опишет декларации для foo() в .c и .h по разному, он хоть получит внятное сообщение о том, что перегрузки в Си не существует
зачем объявлять функцию в module.c, если она там не вызывается ?
это лишний код
module.h нужно подключить только в main.c

Цитата Сообщение от niXman
сообщение о том, что перегрузки в Си не существует
пропускает
f.c
C
1
2
3
4
5
6
#include <stdio.h>
 
void f(void)
{
    printf("f\n");
}
main.c
C
1
2
3
4
5
6
7
int f(int);
 
int main(void)
{
    f(1);
    return 0;
}
Код
[guest@localhost tests]$ .ansi t.c f.c -o t
[guest@localhost tests]$ ./t
f
[guest@localhost tests]$ alias .ansi
alias .ansi='gcc -ansi -pedantic -Wall'
[guest@localhost tests]$

а компилировать через g++ - это накладывать правила из C++ (
пример
t.c
C++
1
char using;
Код
[guest@localhost tests]$ cp t.c t.cpp
[guest@localhost tests]$ g++ -c t.cpp
t.cpp:2:6: ошибка: expected unqualified-id before ‘using’
[guest@localhost tests]$ .ansi -c t.c
[guest@localhost tests]$
)

Добавлено через 5 минут
Цитата Сообщение от fasked
C
1
2
3
4
int foo() {
    /* some code */
    return 0;
}
и в C пустота не означает void
пустота означает, что функция имеет неопределённое число аргументов неопределённых типов (для совместимости с диалектом, который был до C89)
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
22.08.2011, 03:17     Как в include отделить интерфейс от реализации? #13
Цитата Сообщение от accept Посмотреть сообщение
пропускает
потому что декларация не подключена.

Добавлено через 2 минуты
Цитата Сообщение от accept Посмотреть сообщение
зачем объявлять функцию в module.c, если она там не вызывается ?
да потому что в module.h декларации, а в module.c реализации.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.08.2011, 05:27     Как в include отделить интерфейс от реализации?
Еще ссылки по теме:
C++ Builder Как отделить вторичную форму от главной?
Как отделить путь от имени файла с расширением C++ WinAPI
Отделение интерфейса от реализации класса: компиляция кода реализации C++
C++ Как отделить BGI файл от EXE. Как можно внедрить данный модуль в рабочий файл?
#include как и когда? C++

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

Или воспользуйтесь поиском по форуму:
accept
4820 / 3240 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
22.08.2011, 05:27     Как в include отделить интерфейс от реализации? #14
Цитата Сообщение от niXman
потому что декларация не подключена.
да ? подключена она там
это сделано не через #include, а напрямую

Цитата Сообщение от niXman
да потому что в module.h декларации, а в module.c реализации.
зачем в module.c, в котором определение функции, объявлять эту же функцию ?

Добавлено через 18 минут
Цитата Сообщение от niXman
потому что декларация не подключена.
а, ну ясно
сделал через #include
Код
[guest@localhost tests]$ .ansi t.c f.c -o t
f.c:5:6: ошибка: несовместимые типы для ‘f’
t.h:4:5: замечание: здесь была предыдущая декларация ‘f’
[guest@localhost tests]$
Добавлено через 4 минуты
Цитата Сообщение от niXman
лучше подключать.
ибо если он случайно опишет декларации для foo() в .c и .h по разному, он хоть получит внятное сообщение о том, что перегрузки в Си не существует. иначе получит анрезолвед.
даже не unresolved, а просто тишину
Yandex
Объявления
22.08.2011, 05:27     Как в include отделить интерфейс от реализации?
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru