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

Инвестиции: Вопрос-Ответ

  Все выпуски  

C/C++ Вопрос-Ответ Выпуск № 8


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

C/C++ Вопрос-Ответ

Выпуск № 8
Cайт : SoftMaker.com.ru
Архив рассылки : SoftMaker.com.ru
Количество подписчиков : 950
В этом выпуске
От ведущего

Здравствуйте уважаемые подписчики !
Напоминаю, что, как всегда, Вы можете отправить свои пожелания (замечания, предложения, сообщения об ошибках) по поводу рассылки и сайта по этому адресу.
Если вы хотите создать и вести какой либо раздел в этой рассылке - также пишите мне.

С уважением, Вахтуров Виктор.

Подписчикам

Чтобы заранее разрешить возможные недоразумения, прошу Вас помнить, что вопросы публикуются в рассылке только один раз. Поэтому, если Вам не ответили в этом выпуске, или ваш вопрос не был опубликован, пришлите его еще раз. Не стоит отвечать на вопрос, который был задан в предыдущем выпуске (за исключением случая, когда он снова опубликован в этом).

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

Вопросы

Для того, чтобы задать свой вопрос, кликните этой ссылке (вопрос будет опубликован в следующем номере).
Вы можете задавать любые вопросы, касающиеся программирования на языке C и C++. Это могут быть вопросы, касающиеся как конструкций языка, применения библиотек классов, шаблонов (таких как MFC или STL), использования компиляторов, так и самой философии программирования на C или C++. Здесь нет ограничений - спрашивайте и получайте ответы.

Вопрос № 27 ( Mick )

Добрый день!
Ответьте пожалуйста на такой вопрос, дело в том, что я только недавно начал заниматься C++/VC++, скажите пожалуйста, с какой версией лучше работать, с VC++ 6, или с VC++ 2003.NET, ведь VC++ 6 вышел аж в 1998 году, но тем не менее книги этого года выпуска все равно выходят именно по этой версии, порекоммендуйте пожалуйста хорошую литературу по VC++.

Ответить на вопрос

Вопрос № 28 ( rommaa27 )

Добрый день!
Господа подскажите как в VC 6.0 в отладчике (Debug) посмотреть
значение static переменной.

Ответить на вопрос

Вопрос № 29 ( Семён Веремьёв )

Здравствуйте у меня несколько вопросов.Заранее благодарен.
1.Что такое C++ Builder и как с ним работать.
2.Как работать с dos

Ответить на вопрос

Ответы

Ниже приведены вопросы предыдущего выпуска и ответы на них.

Вопрос № 21 ( Валера )

Где бесплатно скачать C Builder 6 ?

Ответ ( Хорошилов Евгений )

Здравствуйте,

www.borland.com

Там надо зарегиться, чтоб тебе на мыло выслали ключ ля временного
пользования.

А потом ищи на www.lomalka.ru, по моему там лекарство есть.

Ответ ( Артём )

Моё почтение.

Скачать???
намного легче зайти в любой магазин и купить всего за 15 грн (75
рублей). Это "тяжелая" программа в отношении количества мегабайт.
А вообще попробуйте Visual C++ 6.0-7.1 - архиудобная штука.

Ответ ( .::A.[LK].S::. )

Бесплатно скачать C++Builder 6 можно в программе eMule, eDonkey, DC++ и тому подобное.
Вот тут можно скачать eMule:
Оффицальный сайт eMule
А вот ссылка для eMule(ОНА БУДЕТ РАБОТАТЬ ТОЛЬКО ЕСЛИ УСТАНОВЛЕН И ВКЛЮЧЁН EMULE):
С++Builder 6 Enterprise [1-5CD ISO]
Вопрос № 22 ( Yulia )

Здравствуйте,
Почему в с++ выскакивает окошко cpu при использовании двумерного
массива типа AnsiString a[1,20], когда он заполняется значениями.
Когда заполняется "первая часть" a[0,0]-a[0,20], то программа
выполняется нормально, когда "вторая часть" a[1,0]-a[1,20] то
выскакиивает это самое окно. Подскажите, что нужно делать?

Ответ ( Hotbox )

Выход за границы массива.
Массив a[1,20] - это массив 1х20, а когда вызывается оператор [] для элемента
a[1,0] обращение идет к элементу 2x1.

Ответ ( Voloshin )

1. двумерный массив определяется как a[N][M]
2. для обработки массива индексы принимают значения 0..N-1 и 0..M-1
в вашем случае
a[1][20] - одномерный массив из 20 элементов, что эквивалентно
определению a[20]
заполняются элементы a[0][0]..a[0][19]
иначе - выход за пределы массива

Ответ ( Evgenej Rogojkin )

Здравствуйте,

Дело в неправильном объявлении/использовании массива.
В языке Си при объявлении массива ты должен указывать
количество элементов в каждой размерности, т.е. запись
AnsiString a[1,20];
означает создать двумерный массив AnsiStringов где первая размерность равна 1, а
вторая - 20. Фактически будет создан одномерный массив AnsiString a[20].
Для того чтобы создать двумерный массив с двумя элементами в первой
размерности должно быть следующее объявление:
AnsiString a[2,20];
При таком объявлении тебе будет доступны как элементы а[0,n] так и
a[1,n]
В общем случае, если ты хочешь создать двухмерный массив размерностью
N*M объявлять его надо так
<type> a[N,M];
обращени к последнему элементу массива будет выглядеть так:
a[N-1,M-1]

Ответ ( Лисенок )

Дык почему же а[0,0]-a[0,20]? если верхняя граница - 20, то
a[0,0]-a[0,19] и все. нету там a[1, 0] и всего остального. Кстати с
таким же успехом можно было написать AnsiString a[20];

Ответ ( Михаил )

Вообще-то изначально в Си нумерация элементов массива начинается с 0.
Поэтому в Вашем случае нужно сделать так:

AnsiString a[2,20];    // двумерный массив по 20 элементов в каждом
for(int i=0,i<20,i++)  // от 0 до 19  ->  20 штук
 { a[0,i]="первая часть";
   a[1,i]="вторая часть";
 } 

Ответ ( NET_PROGA )

Здрасте, товарищъ программер.
Слово зероиндекс что-нибудь тебе говорит? Обьявил ты одномерный массив, а полез во вторую строку. Это тебе не бейсик. :)

Ответ ( g00d )

Во "второй части" ты вводишь данные с свободную область памяти. Она
может использоваться другими программами. Необходимо определить такой
массив AnsiString a[2,20],при чем заполнение вести примерно так:

for(int i=0;i<2;i++)
   for(int j=0;j<20;j++)
        AnsiString[i][j] = "значение";

Ответ ( Sergey Nechaev )

Здравствуйте.

У тебя в массиве 20 элементов, начиная с нуля. Т.е. элемента a[0][20]
и a[1][20] не существует. Ты пишешь в чужую память.

Ответ ( Sergey Shamov )

Если массив объявлен как a[1][20], то он будет содержать один элемент
(с номером 0) по первому измерению и 20 элементов (с номерами 0...19)
по второму. Т.е. цифры в объявлении обозначают не максимальный номер
элемента, а их количество. Максимальный номер всегда будет на единицу
меньше, чем количество элементов, так как нумерация начинается с нуля.

По идее, окошко cpu должно выскакивать раньше, еще при попытке
записать что-либо в элемент с номером 20 в первой части.

Ответ ( Александр Носков )

1. Происходит ошибка защиты памяти.


2. По определению, в языке С++ многомерный массив есть массив массивов, т.е.
массив, элементами которого служат массивы.

Двумерный массив 2х20 определяется следующим образом:

Тип Имя_массива [2][20];

Например: char mystring[2][20]; - две строки по двадцать символов.

Инициализацию этого двумерного массива, можно произвести в цикле:


int k = 65;

char mystring[2][20];

for(int =0; i<2; i++)

{

            for(int j=0; j<19; j++) mystring[i][j] = k + j;

            mystring[i][19] = '/0';

            k = 97;

}


Можно сделать аналогичный двумерный (многомерный) массив в стиле языка С,
где есть только одномерные массивы.

Например:


int k = 65, i, j;

char mystring[40];

for(i=0; i<2; i++)

{

            for(j=0; j<19; j++) mystring[i * 20 + j] = k + j;

            mystring[i * 20 + 19] = '/0';

            k = 97;

}

Ответ ( Maxim Zhigadlo )

Здравствуйте!

Вопрос задан смутно. Но кое-что попробую сказать, может поможет.
1. Задавать массивы надо так.
MY_TYPE a[k][n];
2. У тебя размерности [1][20], что, грубо говоря, тоже самое, что и
просто одномерный массив. В этом может быть и ошибка. Тебе надо
[2][20].
3. При доступе к ячейке массив нумеруется с 0 до n-1. Т. е. при
размерности массива [1][20] ячейки [0][20], и тем более [1][20], просто
не допустимы. (Точнее они допустимы, но при записи в них ты можешь
попасть в не тот участок памяти, и что-нибудь важное убить.)
При размерности [1][20] доступны [0][0]-[0][19].

Ответ ( Дмитрий Брюхацкий )

Нужно учитывать что последним элементом каждой из ваших "частей" будет
a[i][19], а не a[i][20]. Ведь, при объявлении, в квадратных скобках
указывается количество элементов массива, а не номер последнего
элемента. В Вашем случае следовало бы объявлять массив приблизительно
так:
AnsiString a[2][21];

Ответ ( atavin_ta )

В C в скобках указывается не диапазон индексов, а количество элементов.
Поэтому в массиве A[1,20] существуют только элементы A[0,0]-A[0,19], а
элементы A[1,0]-A[1,20] не существуют. Элемент A[1,20] может быть создан во
время исполенения в "дыре" между концом массива и кодом, или между концом
массива и другой переменной. Так как C не проверяет диапазон, то ошибка при
обращении к "дыре", как к элементу массива не возникает, но если происходит
наложение на другие переменные или на код, то возможны самые неожиданные
глюки, иногда на них происходит реакция с всплывающим сообщением об ошибке.
Вопрос № 23 ( Denis Kravtsoff )

Glad to greet!

Наболевший вопрос, связанный с C++ Builder 6.
Имеется форма, на форме TImage. При любой отрисовке на Canvas этого
самого TImage можно заметить моргание всей области изображения
(попытка использовать внеэкранный буфер (второй TImage, на который всё
выводится, а потом копируется на форму) результатов не принесла -
всё то же мерцание). Также пробовал вызывать методы рисования из
FormPaint, но всё без изменений.
Судя по всему, при обновлении вся область под Canvas в начале
перерисовывается цветом форма, а затем поверх этого выводится всё
остальное. Где отловить этот момент, как отключить подобное
автоматическое обновление области формы?
Документация по BCB на этот счёт крайне скупа. Заранее спасибо.

ЗЫ Помогает включение transparent для TForm, но при этом общая
скорость перерисовки заметно падает, что в общем-то и понятно.
Т.е. такое решение не является приемлемым.

Alles Gute!

...In Code We Trust...

Ответ ( .:P@H@N:. // L4M0$ )

Попробу прописать DoubleBuffered = true;
В PaintBox'e помогает.

Ответ ( Maxim Zhigadlo )

Здравствуйте q!

Сам сталкивался с этой проблемой.
Я боролся так.
Создаешь свою, процедуру/класс/еще_что для отрисовки в отдельный
буфер, как ты и предлагал. Его перерисовываешь тогда, когда тебе это
надо. Сам буфер выводишь на экран/в окно при сообщениях WM_PAINT и
WM_SIZE, при том желательно это делать (особенно с WM_SIZE) для всего
окна сразу, поверх старого содержимого с помощью bitblt.
Мне помогало. Миганий ноль/тормоза минимальны.
Если есть вопросы, пиши:
support@lonely-dragon.com
Вопрос № 24 ( atavin_ta )

Отправьте мне, пожалуйста, любой исходник на С/С++, использующий OpenGL.
Можно просто демо-программу, выводящую на экран одно какое-нибудь
изменяющееся или движущееся изображение (водную гладь, вращающийся предмет,
качающеееся лицо). Желательно с комментариями, чтобы я мог разобраться, как
описать свое изображение и положение камеры. Тарас. atavin_ta@pochta.ru.

Ответ ( Karen Hakhumyan )

Привет! В MSDN есть несколько примеров по OpenGL, также можешь посмотреть сайты www.nvidia.com и www.ati.com, там есть очень неплохие примеры. Карен.

Ответ ( Жариков Игорь )

Приветствую

Принцип немерцающей анимации состоит в использовании ДВУХ буферов
изображения. Одна поверхность является активной и ее видно на экране
монитора, а вторая скрыта от пользователя и не видна - на ней то и
производится рисование следующего кадра. Как только следующий кадр
готов производится переключение поверхностей: Активная становится
скрытой, а скрытая - активной. Скорость переключения гораздо выше
скорости прорисовывания (из-за медленности которого и происходит
мерцание). В зависимости от того какой АПИ ты используешь разнятся и
нужные действия. Совершенно точно этот принцип реализуем под
Директом и Опен Джиэлом.
Вопрос № 25 ( atavin_ta )

Я немного не понимаю, как сделать не мерцающую анимацию в C++. Попробовал в событии WM_PAINT рисовать только новые кадры, а старые стирать с помощью InvalidateRect(hwnd,NULL,TRUE), но в результате начинает изображение начинает мерцать, причем мерцают больше неподвижные фрагменты, чем подвижные. Больше всего мерцает кайма вокруг анимируемой области. Попробовал поменять InvalidateRect(hwnd,NULL,TRUE) на InvalidateRect(hwnd,NULL,FALSE), в результате движущиеся объекты начинают оставлять следы. Взял готовый исходник, стираюший старое положение движущихся объектов перед их перерисовкой. после компиляции и запуска стали мерцать именно эти объекты, причем непрерывно, независимо от того, движутся ли они в данный момент, или остановились. Пробовал написать то же самое в делфи, получил вообще призраки движущихся объектов. их мерцание просматривается плохо, но зато частота мерцания такова, что сами объекты оказываются прозрачными. Задача -- прорисовка игрового поля информационного столбца за пределами игрового поля в арканоиде -- игре с прыгающим шариком, разбивающем ящики. Шарик отскакивает от верхней и боковых границ игрового поля, от ящиков и от узкой площадки в нижней части игрового поля, перемещаемой мышью. Площадка выпукла, что позволяет в зависимости от точки касания шарика изменять угол его отскока, либо площадка плоская, но при отскоке шарика от нее законы упругого соударения нарушаются виртуальным контактным полем рассеяния. Внешний вид главного окна программы задуман так, что возможность деления его на дочерние окна представляется сомнительной. Вкладываю два варианта заготовки *. В них еще нет шарика и ящиков, есть только площадка, поле и кайма вокруг него. После загрузки надо нажать . Двойное нажатие -- выход из программы. В Arc1 площадка оставляет след, в Arc2 наблюдается мерцание. Подскажите, как исправить описанные глюки. Тарас.

Ответ ( Evgenej Rogojkin )

Игры никогда ни писал, но нето подобное было.
Мерцание было из-за того что когда приходит сообщение WM_PAINT Windows
автоматически очищает поверхность (или клиентскую чать)
окна. При этом получается эффект мерцания. Отключить стирание окна при
перерисовке можно назначив соответсвующий стиль окну при его создании.
К сожалению на память не помню какой-именно стиль надо назначать.

Ответ ( NET_PROGA )

Тарас, лучше вообще ничего не пишите, особенно игрушку. Вы хоть в сети пробывали искать ответ на свой вопрос?
Чтобы не было мерцания рисовать нужно в скрытый канвас, потом его _разом_ выводить на канвас приложения.
Но если не будете делать на DIRECTX, то ничего динамичного вы не сможете вывести. Замедления и рывки обязательно будут.
И какой ни была бы замечательной игра, на такую дёрганность и заторможенность графики люди смотреть не могут.

Ответ ( Maxim Zhigadlo )

Здравствуйте q!

Смотри мой ответ на вопрос ¦23.
Если есть вопросы, пиши:
support@lonely-dragon.com
Вопрос № 26 ( rasul yusupov )

Помогите! Как вычисляется значение формулы типа P2*(P3-P4)/P5 - P6,
если эта формула находится в какой-то поле базы данных.
Заранее спасибо!

Ответ ( Hotbox )

Не совсем понятен вопрос: ФОРМУЛА находится в БД или ДАННЫЕ (P2, P3 и т.д.)
находятся в БД?
Если ФОРМУЛА, то надо производить синтаксический разбор, а если данные то
можно писать прямо в SQL-запросе в зависимости от языка БД, например:
select (P2*(P3-P4)/P5 - P6) as val from anything

Lexxa

Ответ ( Evgenej Rogojkin )

Формула лежит в поле БД, при считывании из него она у тебя юудет в
виде текстовой строки. В чистом Си/С++ формулу заданную текстовой строкой не
вычислишь. Можешь написать парсер мат.выражений или использовать уже
готовый - в инете их можно легко найти.
Книги по C/C++
Язык программирования Си.
Язык программирования Си.

Автор: Брайан Керниган, Деннис Ритчи

Это - легендарная книга разработчиков языка Си, давно ставшая классикой для всех изучающих и использующих как Си, так и Си++.
Данная книга переработана и дополнена с учетом стандарта ANSI языка C.
Для настоящего третьего русского издания перевод заново сверен с оригиналом, в него внесены некоторые поправки, учитывающие устоявшиеся за прошедшие годы изменения в терминологии, а так же учтены авторские замечания.
Книга будет полезна всем без исключения: программистам, преподавателям, студентам.

Страница книги на Озоне
C++Builder 6. Справочное пособие. Книга 1. Язык С++
C++ Builder 6. Справочное пособие. Книга 1. Язык С++

Автор: А. Я. Архангельский

В книге даются исчерпывающие справочные сведения по языку C++ в C++ Builder 6: синтаксис языка, все операции и операторы, все типы данных. Подробно рассматривается работа с исключениями, с текстовыми и двоичными файлами, со строками разных типов, массивами, множествами, структурами, классами. Обсуждается обработка и генерация сообщений Windows. Рассматривается около 650 функций C, C++, API Windows, из них более 300 с подробными описаниями и примерами.

Страница книги на Озоне
Всего доброго. До встречи в следующем номере.

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.cppqa
Отписаться

В избранное