Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на C / C++


Информационный Канал Subscribe.Ru

РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / C/C++

Выпуск № 202
от 22.09.2005, 19:25

Администратор:Калашников О.А.
В рассылке:Подписчиков: 202, Экспертов: 31
В номере:Вопросов: 5, Ответов: 16


Вопрос № 26461: Я неумею получать из функции структуру, подскажите как правильно это делать желательно пример.... Вот мой неработающий пример: long larray; typedef struct _GS_RGBImageRec { int sizeX, sizeY; unsigned char *data; } gs_DI...
Вопрос № 26464: Здравствуйте уважаемые эксперты! Вот пример из учебника по С++ #include "stdafx.h" #include <iostream> #include <cstdlib> using namespace std; #define IMAXVALUES 10 int icompare_funct(c...
Вопрос № 26481: Уважаемые Эксперты! Что лучше использовать для программирования на С++ : MS VC++ 6.0 (.NET) or C++ Bilder 5.0 (6.0) ? И почему? А у кого получаются наиболее быстрые и компактные программы? (ссылки на форумы с аналогичными вопросами ...
Вопрос № 26488: Здравствуйте, уважаемые эксперты. Я изучаю программирование на DirectX (VC++). Вы не подскажете, каким образом в играх делают свои элементы управления, окошки, кнопки и т. п., которые нарисованы и выглядят по-своему, но работают как стандартные э...
Вопрос № 26492: Здравствуйте!!! Помогите пожалуйста написать программу У меня никак не получается : Создать класс и описать в нем указанные поля. В классе определить конструктор, в котором инициализировать поля случайными, но разумными данными. В классе определи...

Вопрос № 26.461
Я неумею получать из функции структуру, подскажите как правильно это делать желательно пример....

Вот мой неработающий пример:
long larray;
typedef struct _GS_RGBImageRec {
int sizeX, sizeY;
unsigned char *data;
} gs_DIBImageRec;

gs_DIBImageRec *mImage;

gs_DIBImageRec * GDIBImageLoad (AnsiString name){
gs_DIBImageRec *gsdib;
gsdib->sizeX=0;
gsdib->sizeY=0;
if ((FT=fopen(name.c_str(), "rb"))==NULL) return NULL;
fread(&gsdib->sizeX,2,1,FT);
fread(&gsdib->sizeY,2,1,FT);
fread(&larray,4,1,FT); //тут мы получим количество байт для чтения
fread(gsdib->data,1,larray,FT); //сюда все это прочитаем
return gsdib;
};

void main(void){
mImage = GDIBImageLoad ("DATA/title.gdi");
printf("%s",mImage->sizeX);
printf("%s",mImage->sizeY);
printf("%s",mImage->data);
};

Но я на выходе получаю либо ерунду полную, либо немогу вообще это использовать. Помогите ! Подскажите всякие варианты.
Отправлен: 16.09.2005, 19:57
Вопрос задал: DDMZ (статус: Посетитель)
Всего ответов: 4
Мини-форум вопроса >>> (сообщений: 2)

Отвечает: _DM_
Здравствуйте, DDMZ!
Как мне кажется беда в том, что ты не выделяюшь память под массив data, попробуй так:
...
fread(&larray,4,1,FT);
//!!!
gsdib->data = new float [gsdib->larray];
// и потом
fread(gsdib->data,1,larray,FT);
А так ты просто читаешь билеберду какую-то из памяти, когда на экран выводишь.
Если я прав, то sizeX и sizeY должны выводится нормально на экран, особенно если так: printf("%i ",mImage->sizeX);
Ответ отправил: _DM_ (статус: 2-ой класс)
Отправлен: 16.09.2005, 20:08
Оценка за ответ: 5
Комментарий оценки:
Это мой косяк =)
Кстати через new память таким образом выделить неудалось!

А вот так выглядят рабочии функций:
gs_DIBImageRec * GDIBImageLoad (AnsiString name){
//gs_DIBImageRec *gsdib;
gs_DIBImageRec *gsdib=new gs_DIBImageRec;

.....
gsdib->data=(BYTE*)malloc(larray[3]);
fread(gsdib->data,1,larray[3],FT);
return gsdib;
}
void FreeGDIB( gs_DIBImageRec *gsdib){
free(gsdib->data);
delete gsdib;
};

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

Хотя Jadd утверждает что даже так работать будет неправильно. Хотя я если посмотреть исходники дума то он текстуры грузит похожим методом...

Отвечает: Jadd
Здравствуйте, DDMZ!
Так, как ты делаешь, делать нельзя ВООБЩЕ. Объясняю на пальцах. Во-первых. В теле своей функции ты объявляешь переменную на структуру, место в памяти для которой еще не выделено!!!!! Т.е. твой указатель указывает в никуда. Нужно делать так: gs_DIBImageRec *gsdib = new gs_DIBImageRec; В этом случае выделяется память под структуру, которую ты заполняешь, ПРАВИЛЬНО инициализируя все переменные (выделяя память под массивы и прочее). Но, даже так работать будет неправильно, и это Во-вторых. Объясняю почему. Память под структуру выделится где? Правильно. В стеке. Что произойдет со стеком, когда функция перестанет работать? Правильно. Разрушится и данные из стека будут потеряны. Это значит, что возврщенный указатель работать не будет. Я бы, в ситуации, когда нужно в функции инициализировать структуру, сделал бы иначе. Во-первых, прототип выглядел бы так:
//в данном случае неважно что возвращает функция...сделай на свой выбор. Например верни код ошибки
void GDIBImageLoad(AnsiString name, gs_DIBImageRec *gsdib);
Таким образом, после "отработки" функции в структуре останутся данные, которые проинициализировала функция. И все, что тебе нужно, это объявить переменную типа твоей структуры, как
gs_DIBImageRec gsdib;
и передать ее в функцию:
GDIBImageLoad("Data/title.gdi", &gsdib);

Вот, примерно, так. Пиши, коли чего.
---------
Если в сердце дверь закрыта, нужно в печень постучаться
Ответ отправил: Jadd (статус: Практикант)
Отправлен: 16.09.2005, 20:24
Оценка за ответ: 5
Комментарий оценки:
GDIBImageLoad("Data/title.gdi", &mImage); Этот вариант самый простой, и был у меня изначально, но для меня он никак неподходит...
мне необходимо чтобы он возвращал структуру через return. Например так делает функция auxDIBImageLoad как она так сделана?
Или вот например функция из Quake 3 :
bspbrush_t *AllocBrush (int numsides)
bspbrush_t *bb;
......
bb = malloc(c);
Я пробовал у себя выделить через malloc но несмог, поскольку типы несовпали(неумею я malloc использовать) всегда использовал new

Как сделать? Напиши еще ответ...

Отвечает: Raptor1
Здравствуйте, DDMZ!
Что такое получать из функции структуру я не знаю, а в твоем примере я не нашел выделения памяти под структуру gs_DIBImageRec в функции, попробуй добавить
gs_DIBImageRec * GDIBImageLoad (AnsiString name)
{
gs_DIBImageRec *gsdib= new gs_DIBImageRec();
gsdib->sizeX=0;
gsdib->sizeY=0;
if ((FT=fopen(name.c_str(), "rb"))==NULL) return NULL;
fread(&gsdib->sizeX,2,1,FT);
fread(&gsdib->sizeY,2,1,FT);
fread(&larray,4,1,FT); //тут мы получим количество байт для чтения
fread(gsdib->data,1,larray,FT); //сюда все это прочитаем
return gsdib;
};
Ответ отправил: Raptor1 (статус: 7-ой класс)
Отправлен: 17.09.2005, 10:29

Отвечает: Бартунов Сергей Олегович
Здравствуйте, DDMZ!
И вот ты внутри GDIBImageLoad () создаешь !указатель! на gsdib, который НЕ ОПРЕДЕЛЕН, затем по указателю меняешь переменные-члены структуры и думаешь, что будешь счастлив. Увы, надо объявлять обыкновенный объект, не указатель, и работать с ним. Странно, что программа вообще как-то работала.
---------
Небо для Всех
Ответ отправил: Бартунов Сергей Олегович (статус: 3-ий класс)
Отправлен: 18.09.2005, 12:58


Вопрос № 26.464
Здравствуйте уважаемые эксперты!
Вот пример из учебника по С++

#include "stdafx.h"
#include <iostream>
#include <cstdlib>

using namespace std;
#define IMAXVALUES 10

int icompare_funct(const void *iresult_a, const void *iresult_b);
int (*ifunct_ptr)(const void *, const void *);

int _tmain(int argc, _TCHAR* argv[])
{
int i;
int iarray[IMAXVALUES]={0,5,3,2,8,7,9,1,4,6};
ifunct_ptr=icompare_funct;
qsort(iarray,IMAXVALUES,sizeof(int),ifunct_ptr);
for (i=0; i<IMAXVALUES;i++)
{
cout << '{' << i<< '}' <<iarray[i] << endl;
}

return 0;
}

int icoompare_functon(const void *iresult_a, const void *iresult_b)
{
return ((*(int *)iresult_a)-(*(int*)iresult_b));
}

но вопервых он у меня не работает(выдает ошибку ptr error LNK2019: unresolved external symbol "int __cdecl icompare_funct(void const *,void const *)" (?icompare_funct@@YAHPBX0@Z) referenced in function _main)
во-вторых не могу понять что передается в функцию icompare_function().
Объяните пожалуйста.
Отправлен: 16.09.2005, 20:55
Вопрос задал: Ивченков Владислав Владимирович (статус: Посетитель)
Всего ответов: 2
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Jadd
Здравствуйте, Ивченков Владислав Владимирович!
Дык и не должна работать. Вы пытаетесь получить адрес функции, у которой нету реализации. Смотрите листинг внизу. ИМХО вы просто очепятались. Что передается в функцию? А разве из ее определения и реализации не ясно? Передаются какие-то данные (причем произвольного типа, адрес на которые нельзя изменить). В теле функции данные приводятся к интам и возвращается разность между ними. По-моему, все предельно просто. Или Вы видите какой-то иной, скрытый, смысл?
---------
Если в сердце дверь закрыта, нужно в печень постучаться
Ответ отправил: Jadd (статус: Практикант)
Отправлен: 16.09.2005, 21:13

Отвечает: Raptor1
Здравствуйте, Ивченков Владислав Владимирович!
Эту функцию ты должен написать сам, а в твоем примере в ее описании лишняя буква о, поэтому она оказывается неопределена, а передеется в нее два указателя на объекты, которые ты должен сравнить и в вернуть

< 0 elem1 less than elem2
0 elem1 equivalent to elem2
> 0 elem1 greater than elem2
Ответ отправил: Raptor1 (статус: 7-ой класс)
Отправлен: 17.09.2005, 10:30


Вопрос № 26.481
Уважаемые Эксперты!
Что лучше использовать для программирования на С++ :
MS VC++ 6.0 (.NET) or C++ Bilder 5.0 (6.0) ? И почему? А у кого получаются наиболее быстрые и компактные программы?

(ссылки на форумы с аналогичными вопросами не очень интересуют, любопытно мнение и аргументы экспертов)
Отправлен: 17.09.2005, 08:29
Вопрос задал: Ahab (статус: 2-ой класс)
Всего ответов: 5
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Romodos
Здравствуйте, Ahab!
В принципе, для новичка лучше Builder. Там формы не надо создавать самому, можно поручить это VCL. А в Visual C надо подключать диалоги или писать окна на WinAPI, что довольно трудоемко. Но потом привыкаешь.
В принципе, скорость примерно та же. Насчёт размера не знаю.
Т.е. для профессиональных или корпоративных продуктов нужет вижуал си, а для маленьких личных проектов отлично подойдёт билдер.
---------
FAQ me off!
Ответ отправил: Romodos (статус: 7-ой класс)
Отправлен: 17.09.2005, 09:24
Оценка за ответ: 5
Комментарий оценки:
Насколько пробовал и то и то пришёл к такому же мнению :) Интересно, то что они одновременно стоят на компе, они друг другу не мешают? Пока вроде не замечал ничего...

Отвечает: Alex Diesel
Здравствуйте, Ahab!
Для программирования на чистом С++, таком какой описан например у Страуструпа можно использовать любую среду разработки - все-равно вам должен оттудова понадобится только компилятор и иже с ним, которые, например Борланд вообще бесплатно распространяет.

Если речь идет о создании графических приложений. Обе среды раззработки естетсвенно позволяют использовать WinAPI плюс в VS включена библиотека MFC упрощающая разработку, у Борланда также есть своя библиотека, один в один такая же как в Делфи. Плюс средства разработки. Считается что перетаскивать кнопочки на форму в билдере значительно проще чем перетаскивать кнопочки на форму в MS VS. Это действительно так, возможно наклепать сетевой тетрис в Борландовском продукте действительно проще для новичка который не привык читать докумментацию к ПО которым он пользуется. Действительно в VS процесс несколько интуитивно не понятен, но при прочтения хоть минимума документации все станет на свои места. Если речь идет о создании более-менее серьезных приложений, то возможно легче будет использовать VS, хотя возможно это несколько субъективно - я с ним больше работал. Мне кажется при использовании Билдера есть опасность "залететь" в сферу поиска "дополнительных" компон! ентов ... кода процесс разработки сводится к настройке и присобачивания конкретного компонента к программе, что подтвержает бОльшая половина вопросов этой рассылки.

Короче, я бы на вашем месте обратил внимание на VS. Хотя для изучения языка С++ среда разработки особого значения не имеет.
Ответ отправил: Alex Diesel (статус: Студент)
Отправлен: 17.09.2005, 10:17
Оценка за ответ: 5
Комментарий оценки:
довольно объективный ответ... спасибо...

Отвечает: Jadd
Здравствуйте, Ahab!
Этот вопрос неправомочен. Используй то, что тебе ближе. Я лично сначала начинал писать (если говорить об этих средах) на ВСВ, а сейчас на VC и не собираюсь оюратно менять. У VC намного лучше оптимизатор кода. Но у ВСВ есть одно неоспоримое преимущество. Если тебе нужно быстро написать приложение для БД со множеством форм, то ВСВ - лучше. Во всех остальных случаях (собственный опыт) я бы предпочел VC (уж больно много "навернуто" на ВСВ и слишком много глюков). А насчет скорости и компактности кода - у РС Magazine были тесты и выводы.
---------
Если в сердце дверь закрыта, нужно в печень постучаться
Ответ отправил: Jadd (статус: Практикант)
Отправлен: 17.09.2005, 11:44

Отвечает: Бартунов Сергей Олегович
Здравствуйте, Ahab!
Мое мнение: гораздо лучше использовать g++, ибо он открытый (бесплатный + свободно распространяемый исходный код (gnu.org)) и перенесен на огромное количество платформ. Под него нету офигенных IDE вроде VS, но есть и вполне приличные, вроде Dec-C++ (bloodshed.net). Достаточно хорошо оптимизирует output, но для win32, конечно, отстает от VC++.

Вообще, если встал именно такой жесткий выбор, то я решительно рекомендую VC++! Builder производит более медленный код (см. статью в RSDN о C++-компиляторах), вообще хуже, чем VC++ оптимизирует, как под размер, так и под скорость и т.д. Что же касается соотвествия последним стандартам C++, то некоторые места ни один компилятор не переваривает (!), а в сложных шаблонных конструкциях банально лагает, извергая код с nop'ами вместо реальных инструкций. VC++ более дружественен к начинающим, хотя этим же может раздражать экспертов, но так или иначе, сам язык он переваривает лучше и быстрее.
---------
Небо для Всех
Ответ отправил: Бартунов Сергей Олегович (статус: 3-ий класс)
Отправлен: 17.09.2005, 19:01
Оценка за ответ: 5

Отвечает: Rusland
Здравствуйте, Ahab!
MSV однозначно, хотя бы исходя из того что Borland c 2002 года не поддерживает CBuilder. Удачи.
---------
Тише едешь, дальше будешь... от того места куда едешь
Ответ отправил: Rusland (статус: Студент)
Отправлен: 19.09.2005, 09:33
Оценка за ответ: 5


Вопрос № 26.488
Здравствуйте, уважаемые эксперты.
Я изучаю программирование на DirectX (VC++). Вы не подскажете, каким образом в играх делают свои элементы управления, окошки, кнопки и т. п., которые нарисованы и выглядят по-своему, но работают как стандартные элементы Windows. Я пробовал делать TextBox в виде картинки, но ни о каком Clipboard не могло быть даже и речи.
Пример, окно консоли в HL2, кнопки и прокрутка в Warcraft 3...
Отправлен: 17.09.2005, 13:21
Вопрос задал: Palpatin (статус: Посетитель)
Всего ответов: 1
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Rusland
Здравствуйте, Palpatin!
В directx sdk есть примеры где используются элементы управления. Посмотрите там (папка Samples). Удачи.
---------
Тише едешь, дальше будешь... от того места куда едешь
Ответ отправил: Rusland (статус: Студент)
Отправлен: 19.09.2005, 09:40


Вопрос № 26.492
Здравствуйте!!! Помогите пожалуйста написать программу У меня никак не получается :
Создать класс и описать в нем указанные поля. В классе определить конструктор, в котором инициализировать поля случайными, но разумными данными. В классе определить деструктор, который будет удалять из памяти все динамически созданные в класс переменные. Также перегрузить операторы сравнения (==), присваивания (=) и вывода в поток (<<): ПЕРСОНА: имя – char*; возраст – int; пол – int(bool)

Компилятор выдает ошибки:
[Linker Error] Unresolved external 'person::~person()' referenced from C:AD36PROVERKA.OBJ
[Linker Error] Unresolved external 'person::person(char *)' referenced from C:AD36PROVERKA.OBJ
[Linker Error] Unresolved external 'person::person(int, int)' referenced from C:AD36PROVERKA.OBJ

Я не могу понять из-за чего ??? Помогите пожалуйста!!!!!!!!
Если можно то пришлите свою версию этой программы на rewer8@mail.ru

Приложение:

Отправлен: 17.09.2005, 16:57
Вопрос задал: Rewer8 (статус: Посетитель)
Всего ответов: 4
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Бартунов Сергей Олегович
Здравствуйте, Rewer8!

У тебя несколько проблем:
1) Посмотри на директивы препроцессора, там в двух разных файлах написан одинаковых код:
#ifndef PersonH
#define ...,

при компиляции одного из них, второй не будет включен в компилируемый код.

2) Ты используешь старые STL-библиотеки, <iostream.h>, это не слишком смертельно, но на то они и устаревшие...

3) У тебя банальные синтаксические ошибки в настоящем H-нике.

Приложение:

---------
Небо для Всех

Ответ отправил: Бартунов Сергей Олегович (статус: 3-ий класс)
Отправлен: 17.09.2005, 18:52
Оценка за ответ: 5

Отвечает: _DM_
Здравствуйте, Rewer8!
Чего то вы намудрили, особенно с #ifndef и #endif. И что это у вас ещё за #include "Person.h" - там что, ещё одна персона?
Компилятор ругается вот почему:
когда вы в первый раз написали #ifndef PersonH то тем самым сказали компилятору: если строка PersonH не определена делай следующее. Затем вы объявляете класс и пишите #endif (т.е. говорите компилятору делать до этого места), а затем у вас опять: если строка PersonH не определена, но ведь она то уже определена!!! и компилятор следуующий до #endif кусок, т.е. до конца файла, а потом не может найти определенные в ЭТОМ КУСКЕ члены класса отсюда и ошибка.
Ваш код должен выглядеть примерно так как в приложении.
Переоформите вашу библиотеку и все заработает.
з.ы. И зачем включать библиотеку саму в себя??? #include "Person.h"

Приложение:

Ответ отправил: _DM_ (статус: 2-ой класс)
Отправлен: 17.09.2005, 20:21
Оценка за ответ: 5

Отвечает: Raptor1
Здравствуйте, Rewer8!
Вот чудак, зачем же ты в CPP файле поставил #ifndef PersonH, если этот макрос у тебя определен в включаемом h файле,
Далее примерно то что ты хочешь, тебе остается расставить комментарии

Это h файл
// Person.h: interface for the CPerson class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(__PERSON__H__INCLUDED__)
#define __PERSON__H__INCLUDED__

#include <iostream.h>
class CPerson
{
public:
CPerson(int nAge=12, BOOL bMale=TRUE,char* pszName=NULL);
virtual ~CPerson();

BOOL GetSex() const {return m_bMale;}
int GetAge() const {return m_nAge;}
char* GetName() const {return m_pszName;}
CPerson& operator = (const CPerson& objSrc);
int operator == (const CPerson& objSrc) const;
friend ostream& operator<< ( ostream& os, CPerson& objSrc );
private:
BOOL m_bMale;
int m_nAge;
char* m_pszName;
};

#endif // !defined(__PERSON__H__INCLUDED__)

Это cpp файл
// Person.cpp: implementation of the CPerson class.
//
//////////////////////////////////////////////////////////////////////

#include "Person.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CPerson::CPerson(int nAge, BOOL bMale, char* pszName) : m_nAge(nAge), m_bMale(bMale), m_pszName(NULL)
{
if(NULL!=pszName)
{
m_pszName= new char[strlen(pszName)+1];
strcpy(m_pszName,pszName);
}
}

CPerson& CPerson::operator = (const CPerson& objSrc)
{
m_nAge=objSrc.GetAge();
m_bMale=objSrc.GetSex();
if(NULL!=m_pszName)
{
delete [] m_pszName;
m_pszName=NULL;
}

if(NULL!=objSrc.GetName())
{
m_pszName= new char[strlen(objSrc.GetName())+1];
strcpy(m_pszName,objSrc.GetName());
}
return *this;
}

int CPerson::operator == (const CPerson& objSrc) const
{
if((m_nAge!=objSrc.GetAge())||(m_bMale!=objSrc.GetSex())||(strcmp(m_pszName,objSrc.GetName())!=0))
return 0;
return 1;
}

CPerson::~CPerson()
{
if(NULL!=m_pszName)
{
delete [] m_pszName;
m_pszName=NULL;
}
}

ostream& operator<< ( ostream& os, const CPerson& objSrc)
{
os <<objSrc.GetAge()<<' '<<objSrc.GetSex()<<' '<<objSrc.GetName();
return os;
}

Ответ отправил: Raptor1 (статус: 7-ой класс)
Отправлен: 18.09.2005, 12:22
Оценка за ответ: 5

Отвечает: Jadd
Здравствуйте, Rewer8!
Нужно убрать из cpp файла следующие строки:
#ifndef PersonH
#define PersonH
*********
#endif
---------
Если в сердце дверь закрыта, нужно в печень постучаться
Ответ отправил: Jadd (статус: Практикант)
Отправлен: 18.09.2005, 12:55


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2005, RusFAQ.ru, Россия, Москва. Все права защищены.
Идея, дизайн, программирование, авторское право: Калашников О.А.

Яндекс


Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.cplus
Отписаться
Вспомнить пароль

В избранное