![]() |
![]() |
![]() |
Таблица умножения на Си++
Кто
въехал в этот язык, смотрят на остальных свысока. Обилие необычных типов данных,
особенностей, нестандартностей, исключений поражает новичка и заставляет его с
подобострастием смотреть на тех, кто с легкостью бросается сишными терминами.
- Ну ко попробуем нашу табличку умножения написать на этом великом и могучем. С чего начнем? Конечно же, консольное приложение....
// Таблица умножения на C++. Консольное
приложение. // Подключаем дополнительные заголовочные файлы #include <condefs.h> #include <stdio.h> #include <stdlib.h> #include <iostream.h> #include <conio.h> // заканчиваем (прерываем) список заголовочных файлов, для ускорения // компиляции. #pragma hdrstop // Начало главной функции int main(int argc, char* argv[]) { // Объявление переменных. int somn, i, pr; // Запрос для ввода первого сомножителя cout << "Input first number. "; // Введенные с клавиатуры данные попадают во входной поток // и присваиваются переменной somn cin >> somn; // Организация цикла вычислений for (i=1; i<=10; i++) { // Вычисление произведения pr = somn * i; // Формирование результата и направление его в поток вывода cout << somn << " x " << i << " = " << pr << endl; } // Окончание цикла вычислений и вывода // Ожидание нажатия клавиши getch(); return 0; // Главная функция после удачного выполнения возвращает 0 } |
- И чем же этот код
отличается от простого Си.
- Если интересно посмотри выше, то о чем ты просишь мы уже проходили.
- И как же там с размером файла программы. Ничего
себе: почти 170 килобайт. Кому и зачем может потребоваться такое консольное
приложение. А что ни будь обычное для Windows.
- Давай попробуем. Среда программирования С-Builder
от Borland ничем оособенным
не выделяется: накидал кнопок да
Едитов, а о кодировании и говорить не приходится. Ну,
что, вперед...
// Программа: таблица умножения
на C++ // Вариант с использованием VCL, то есть Visual Component Library // О чем мы сразу же и предупреждаем нашу программу #include <vcl.h> // Обрываем список заголовочных файлов #pragma hdrstop // Но добавляем наш, где описаны все компоненты, которые использовала наша программа, // а также объявления функций. #include "tab_um_cpp.h" //--------------------------------------------------------------------------- #pragma package(smart_init) // В файле с расширением dfm описаны использованные нами ресурсы #pragma resource "*.dfm" // Объявляем переменную Form1, типа TForm1 TForm1 *Form1; // Казалось бы функция ничего не делает, но это кажущаяся бесполезность // Именно она и показывает нашу форму (окно) на экране __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } // Вот она наша главная функция, которая и выполняет всю работу void __fastcall TForm1::Button1Click(TObject *Sender) { // Объявляем необходимые переменные int Somn; char szBuf[1]; // Поместим в символьную переменную только первый символ из поля редактирования // если мы ошиблись при вводе и поместили туда многозначное число StrLCopy(szBuf, Edit1->Text.c_str(),1); //И вернем это число в полее ввода Edit1->Text=szBuf; // Как в старом добром Паскале преобразуем символное значение в целое Somn = StrToInt(Edit1->Text); // Очистим текстовое поле перед выводом Form1->Memo1->Clear(); // Организуем формирование символьной строки в цикле получая произведение перед // выводом for (int K=1; K<11; K++) { Form1->Memo1->Text = Memo1->Text + IntToStr(Somn)+ " x " + IntToStr(K) + " = " + IntToStr(Somn*K) + CHAR(13)+ CHAR(10); } } // Работа функции, вызываемой в ответ на нажатие кнопки на форме завершена // А это реакция на кнопочку, которая заканчивает работу приложения void __fastcall TForm1::Button2Click(TObject *Sender) { Application->Terminate(); } // В заключение мельком упомяну о некоторых вещах, о которых не рассказал // внутри кода. // -> это оператор косвенного доступа к элементам структур. В отличии от простой //точки между элементами, которая выполняет прямой доступ к ним. // :: это оператор разрешения видимости. Он позволяет обращаться к глобальным переменным. |
- В программах на C++ множество мелочей, которые трудно объяснить логическими обоснованиями. Чаще всего вы даже в очень толковой документации увидите объяснение: это нужно делать вот так, чтобы получить вот это. Я не великий знаток C++. Введите название непонятного термина в строке поиска в Интернете. Вы наверняка найдете кучу ссылок, которые смогут вам помочь.
![]() |
- Вроде получилось. Смотри работает. А размер программы 25 с
небольшим килобайт: неплохо.
- Да. программа и
код компактны. Как будь-то это совсем и не Windows-программа.
Создается визуально, выглядит странно. А, что, если без выкрутасов.
- Давай попробуем без выкрутасов.
//Таблица
умножения на C++ без использования VCL на чистом API #include <vcl.h> // А зачем тогда строчка выше этой? // Да, каюсь, в программе пришлось // воспользовался несколькими функциями из этого набора #include <windows.h> #include <stdio.h> // В файле ресурсов всего одна строчка про оригинальную иконку (NK) // Даже в простой программе нельзя терять лицо фирмы USERES("nk.RES"); // Объявление указателей на компоненты нашей программы HWND LTEXT; HWND sED1; HWND sED2; HWND sBUTT1; //Объявление нашей оконной функции со специальным указателем на то, // что она является функцией обратного вызова LRESULT CALLBACK TabUmnWndProc ( HWND, UINT, UINT, LONG); //Наша главная функция и куча параметров для ее вызова int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR IpszCmdParam, int nCmdShow ) { // Объявление локальных переменных HWND hWnd; WNDCLASS WndClass; MSG Msg; char szClassName[]= "TABUMN"; /* Заполняем структуру типа WNDCLASS */ WndClass.style = CS_HREDRAW | CS_VREDRAW; WndClass.lpfnWndProc = TabUmnWndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = hInstance; WndClass.hIcon = LoadIcon (hInstance, "MYICON"); WndClass.hCursor = LoadCursor(NULL, IDI_APPLICATION); WndClass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = szClassName; /* Регистрируем создаваемый класс */ if ( !RegisterClass(&WndClass)) { // Если класс почему то не зарегистрировался, выдадим сообщение MessageBox(NULL,"Проблемы при регистрации класса","Егтог", MB_OK); return 0; } // А если класс зарегистрировался то создадим его его экземпляр: наше окно hWnd = CreateWindow(szClassName, " Таблица умножения", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 260, 350, NULL, NULL, hInstance, NULL); // В этом же окне создадим наши элементики интерфейса // Как оказывается, это тоже окна. // Например, это окошко - просто текст на экране. // Во многих визуальных языках его Label называют. // А мы его в два счета: раз и на форме, то есть в окне LTEXT=CreateWindow("STATIC", "Введи сомножитель", WS_CHILD | WS_VISIBLE | SS_CENTER | WS_BORDER, 15, 20, 160, 20, hWnd, NULL, hInstance, 0); // А теперь окошечко текстового редактирования (однострочное) sED1=CreateWindow("EDIT", "0", WS_CHILD | WS_VISIBLE | WS_BORDER, 15, 52, 60, 25, hWnd, NULL, hInstance, 0); // А теперь кнопочку sBUTT1=CreateWindow("BUTTON", "Расчет", WS_CHILD | WS_VISIBLE | WS_BORDER, 170, 90, 60, 30, hWnd, NULL, hInstance, 0); // А теперь окно редактирования многострочное sED2=CreateWindow("EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE, 15, 90, 130, 200, hWnd, NULL, hInstance, 0); /* Покажем наше главное окно, и заставим прорисоваться */ ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); /* А теперь все тот же цикл получения и обработки сообщений */ while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } // И передача нашей оконной функции, полученных сообщений return Msg.wParam; } //А теперь сама оконная функция LRESULT CALLBACK TabUmnWndProc (HWND hWnd, UINT Msg, UINT wParam, LONG lParam) { // Локальные переменные char szBuf[2]; int iSomn; int iPr; char lpBuf[1000]; char sTemp[1]; // Одно из узких мест Си - хлеб для хакеров. ??? // Переключатель выбора реакции на сообщения switch(Msg) { // Если поступило сообщение с командой то посмотрим, // что там нужно выполнять case WM_COMMAND: { // Ага это наша кнопка if (lParam == INT(sBUTT1)) { // Тогда в переменную szBuf поместим данные из поля ввода // первого сомножителя. GetWindowText(sED1, szBuf, 2); // Очистим исходную строку, если в ней больше одной цифры strcpy(lpBuf, sTemp); // И забросим число в то же самое окно ввода SetWindowText(sED2, lpBuf); // А теперь цикл вывода результатов перемножения for (int K=1; K<11; K++) { // Вот, как раз функция из VCL, о которых я упоминал вначале iSomn=StrToInt(szBuf); // Получим произведение iPr = iSomn * K; // Сформируем временную строку с частью вывода. // Ну нет в СИ строчных переменных: вот и приходится так изголяться sprintf(sTemp, "%d x %d = %d", iSomn, K, iPr); // Закинем эту переменную в буфер для вывода strcat(lpBuf, sTemp); // Теперь сформируем остаток для перевода вывода на другую строку sTemp[0]='\r'; sTemp[1]='\n'; sTemp[2]='\0'; // Сначала добавим к нашей строке. // А потом, подготовленную строку к буферу strcat(lpBuf, sTemp); } // Теперь наш символьный буфер с сформированной строкой // в текстовое поле. SetWindowText(sED2, lpBuf); } // после выполнения вернем 0, ведь это же функция, // она обязана чего то возвращать return 0; } // Обработаем еще одно сообщение, которое командует нашей программе // сворачивать работу case WM_DESTROY: PostQuitMessage(0); return 0; } // А все обилие сообщений по операциям работы с окном и // другие полезные вещи заставим обрабатывать функцию по умолчанию. return DefWindowProc(hWnd, Msg, wParam, lParam); } |
- Что то в этом C++ -
ном коде до боли знакомое. А вспомнил! Это же очень
напоминает Ассемблер, а как с размером? 12800
байт - почти рекорд.
- Как код то меняется, а ведь практически одно и то же. Но
разница между консольным приложением, программой с VCL
и программой на API очень существенная. Вот и скажи
потом, что программирование это не творчество.
![]() |
![]() |
![]() |
Другая информатика. (C) Публикация на draginf.ru. При использовании материалов ссылка на сайт обязательна. |