информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяSpanning Tree Protocol: недокументированное применениеГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Microsoft обещает радикально усилить... 
 Ядро Linux избавляется от российских... 
 20 лет Ubuntu 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / beginners
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Господа, будьте снисходительны, не бросайтесь сразу штрафовать за, как вам кажется, глупые вопросы - 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) может кто угодно, а реализация в любом случае должна быть одна. То есть объявлять о желании использовать переменную могут любые модули. А выделять реальную память (определять переменную) под нее должна только реализация.
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach