Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
Господа, будьте снисходительны, не бросайтесь сразу штрафовать за, как вам кажется, глупые вопросы - beginners на то и beginners.
|
Вопрос про структуры в C/C++ 12.06.03 00:43 Число просмотров: 1097
Автор: dl <Dmitry Leonov> Отредактировано 12.06.03 00:57 Количество правок: 1
|
> Пусть дана некая структура, описанная в файле 1.c. Вопрос: > как получить доступ к ее полям из файла 2.c? Пробовал > объявить ее в 2.с как extern, но что-то не помогает. Или > руки кривые у меня :) > Объясните пожалста что тут к чему :))
Повторить описание. А еще лучше, описать ее внутри 1.h и включить 1.h в оба c-файла. Поскольку компилятор работает на уровне отдельных файлов, он ничего не знает о полях структуры, описанных в соседнем файле. Extern же лишь говорит о том, что не надо здесь и сейчас резервировать место под данную переменную, и означает обещание программиста, что она будет определена где-то еще. Нарушит обещание - получит ошибку линкера.
|
<beginners>
|
Вопрос про структуры в C/C++ 12.06.03 00:05
Автор: dzen Статус: Незарегистрированный пользователь
|
Пусть дана некая структура, описанная в файле 1.c. Вопрос: как получить доступ к ее полям из файла 2.c? Пробовал объявить ее в 2.с как extern, но что-то не помогает. Или руки кривые у меня :)
Объясните пожалста что тут к чему :))
|
|
Вопрос про структуры в C/C++ 12.06.03 00:43
Автор: dl <Dmitry Leonov> Отредактировано 12.06.03 00:57 Количество правок: 1
|
> Пусть дана некая структура, описанная в файле 1.c. Вопрос: > как получить доступ к ее полям из файла 2.c? Пробовал > объявить ее в 2.с как extern, но что-то не помогает. Или > руки кривые у меня :) > Объясните пожалста что тут к чему :))
Повторить описание. А еще лучше, описать ее внутри 1.h и включить 1.h в оба c-файла. Поскольку компилятор работает на уровне отдельных файлов, он ничего не знает о полях структуры, описанных в соседнем файле. Extern же лишь говорит о том, что не надо здесь и сейчас резервировать место под данную переменную, и означает обещание программиста, что она будет определена где-то еще. Нарушит обещание - получит ошибку линкера.
|
| |
Вопрос про структуры в C/C++ 12.06.03 01:13
Автор: dzen Статус: Незарегистрированный пользователь
|
> Повторить описание. А еще лучше, описать ее внутри 1.h и > включить 1.h в оба c-файла. Поскольку компилятор работает > на уровне отдельных файлов, он ничего не знает о полях > структуры, описанных в соседнем файле. Extern же лишь > говорит о том, что не надо здесь и сейчас резервировать > место под данную переменную, и означает обещание > программиста, что она будет определена где-то еще. Нарушит > обещание - получит ошибку линкера.
А не значит ли это, что в двух с-файлах будет ДВЕ структуры с разными значениями в этих полях? Мне-то нужна одна структура (некий общий объект), к которой можно обращаться из 2-х файлов и читать/изменять эти поля.
С переменными, например, проходит все номально. Если она где-то определена, то сделай ее extern в другом файле - и ты имеешь к ней доступ (ну или через указатели, что проще).
|
| | |
Вопрос про структуры в C/C++ 12.06.03 01:30
Автор: dl <Dmitry Leonov>
|
> А не значит ли это, что в двух с-файлах будет ДВЕ структуры > с разными значениями в этих полях? Мне-то нужна одна > структура (некий общий объект), к которой можно обращаться > из 2-х файлов и читать/изменять эти поля. > С переменными, например, проходит все номально. Если она > где-то определена, то сделай ее extern в другом файле - и > ты имеешь к ней доступ (ну или через указатели, что проще).
Структура - это не объект, это задание типа будущего объекта, описание того, из чего будет состоять переменная этого типа, когда она будет создана. Можно наобъявлять хоть миллион структур, в скомпилированный код они никаким образом не попадут, пока не будут созданы переменные. Естественно, стоит следить за одинаковым описанием одних и тех же структур в разных файлах, именно для этого и используются .h-файлы.
|
| | | |
Вопрос про структуры в C/C++ 12.06.03 01:56
Автор: dzen Статус: Незарегистрированный пользователь
|
> Структура - это не объект, это задание типа будущего > объекта, описание того, из чего будет состоять переменная > этого типа, когда она будет создана. Можно наобъявлять хоть > миллион структур, в скомпилированный код они никаким > образом не попадут, пока не будут созданы переменные. > Естественно, стоит следить за одинаковым описанием одних и > тех же структур в разных файлах, именно для этого и > используются .h-файлы.
Так, стоп... давай на примерах :) Допустим есть у меня такая структура:
struct s{
int a;
int b;
};
И я создаю общую переменную, которую я хочу использовать из тех 2-х файлов:
struct s new_s;
И все это определено в неком .h файле. Я подключаю его и к 1.с и к 2.с => оба файла видят эту переменную (new_s). Потом я вызываю функцию f параметром которой должна быть эта структура (т.е. чтобы в функции я мог менять значения ее полей ... как я понимаю, параметром должна быть ссылка):
void f(struct new_s* tmp)
{
;
}
Но что-то все равно не получается (компилятор отказывается принимать такой параметр функции ... ).
Блин. Что-то я совсем запутался :)
|
| | | | |
Вопрос про структуры в C/C++ 12.06.03 02:12
Автор: dl <Dmitry Leonov>
|
> И все это определено в неком .h файле. Я подключаю его и к > 1.с и к 2.с => оба файла видят эту переменную (new_s). > Потом я вызываю функцию f параметром которой должна быть > эта структура (т.е. чтобы в функции я мог менять значения > ее полей ... как я понимаю, параметром должна быть ссылка): > void f(struct new_s* tmp) > Но что-то все равно не получается (компилятор отказывается > принимать такой параметр функции ... ).
Естественно, потому что new_s - это не имя типа.
file.h:
struct s
{
int a;
int b;
};
extern struct s new_s;
-----------------------
file1.c:
#include "file.h"
struct s new_s;
-----------------------
file2.c
#include "file.h"
void f(struct s* tmp)
{
//...
}
//....
void g()
{
f(&new_s);
}
---
|
| | | | |
Вопрос про структуры в C/C++ 12.06.03 02:06
Автор: amirul <Serge> Статус: The Elderman
|
> Так, стоп... давай на примерах :) Допустим есть у меня > такая структура: > struct s{ > int a; > int b; > }; В .h засовываешь только это ^^^
И еще желатеально засунуть туда объявление объекта. То бишь как и говорил dl пишешь extern struct s new_s;
> И я создаю общую переменную, которую я хочу использовать из > тех 2-х файлов: > struct s new_s; Выбираешь один из .c файлов и в одном определяешь структуру (то есть делаешь то что и написано - без extern). Определение должно быть только в ОДНОМ c файле, а объявление включится вместе с .h во все.
> И все это определено в неком .h файле. Я подключаю его и к > 1.с и к 2.с => оба файла видят эту переменную (new_s). > Потом я вызываю функцию f параметром которой должна быть > эта структура (т.е. чтобы в функции я мог менять значения > ее полей ... как я понимаю, параметром должна быть ссылка): > void f(struct new_s* tmp) > { > ; > } Не так. Во первых это не ссылка (ссылки появились в C++), а указатель. Во вторых следует различать ТИП переменной и САМУ переменную. В данном случае переменная new_s имеет тип (struct s), следовательно прототип функции будет следующим
void f(struct s *);
А вызываться будет так:
f(&new_s);
> Но что-то все равно не получается (компилятор отказывается > принимать такой параметр функции ... ). > Блин. Что-то я совсем запутался :) Нужно прочувствовать разницу между типом объекта и самим объектом. Успехов :-)
|
| | | | | |
Вопрос про структуры в C/C++ 12.06.03 02:25
Автор: dzen Статус: Незарегистрированный пользователь
|
УРАААААА!!!! ОНА РАБОТАЕТ!!! :)))) ... кхм ... что это я
Спасибо всем! Теперь вот хоть разобрался.
|
| | | | | | |
Криво - как ятаган! Но столь же эффективно... 14.06.03 06:19
Автор: Zef <Alloo Zef> Статус: Elderman
|
еще в "детстве" методом научного тыка установил, что делать надо именно так и стех пор не перестаю изумляться - почему такая кривизна?
Логически очевидно: все глобальные переменные должны объявляться в хидере проекта, а компилер сам должен был бы разбираться - раз имя хидера совпадает с именем проекта то под все объявленные в нем переменные место выделяется один раз и "на всегда" с доступом из всех .с, в которые он инклюдится.
Почему сделано не так?
|
| | | | | | | |
Потому что надо знать как работает компилятор (не Urix-like) 14.06.03 10:23
Автор: Ktirf <Æ Rusakov> Статус: Elderman Отредактировано 14.06.03 10:24 Количество правок: 1
|
Компилятор проходит через единицы компиляции совершенно независимо! Инстанцировать переменную, определенную в хедере, в одной единице компиляции (сиречь .c/.cpp-файле) и не сделать этого в другой единице компиляции он в принципе не может, потому что не знает о существовании более чем одной единицы компиляции. Об этом знает линкер, но линкер не может добавлять или удалять такой код, он только связывает отдельные объектные файлы.
Определение и объявление: это две большие разницы.
|
| | | | | | | | |
Предупреждая возможные возражения 14.06.03 17:40
Автор: amirul <Serge> Статус: The Elderman
|
Полностью согласен со сказанным, но думаю могут возникнуть некоторые вопросы.
> Компилятор проходит через единицы компиляции совершенно > независимо! Инстанцировать переменную, определенную в > хедере, в одной единице компиляции (сиречь .c/.cpp-файле) и > не сделать этого в другой единице компиляции он в принципе > не может, потому что не знает о существовании более чем > одной единицы компиляции. Об этом знает линкер, но линкер
Незнание о других единицах трансляции это "by design" и вводилось как преимущество языка, а не как ограничение. Компиляция со всеми ее синтаксическими и другими анализами, и особенно оптимизацией - сравнительно медленный процесс. Компоновка же (линковка) - несравненно быстрее. Поэтому при фиксаньи баги всего в одном файле не нужно перекомпилировать ВЕСЬ проект (возможно и в не один миллион строк). Достаточно перекомпилировать измененный файл и пересобрать его со старыми откомпилированными объектниками.
Раздельная компиляция это основа модульного программирования. При котором в пределах модуля можно производить ЛЮБЫЕ изменения, если не затрагивается его внешний интерфес. Внешний интерфес модуля как раз и выносится в .h файл, а реализация остается в .c
> не может добавлять или удалять такой код, он только > связывает отдельные объектные файлы. > Определение и объявление: это две большие разницы. Использовать модуль при помощи его интерфейса (подключая .h) может кто угодно, а реализация в любом случае должна быть одна. То есть объявлять о желании использовать переменную могут любые модули. А выделять реальную память (определять переменную) под нее должна только реализация.
|
|
|