• Работа с графикой. С++ builder. Как нарисовать рамку вокруг рисунка?

    SerJook
    @SerJook
    кодер
    В зависимости от того, какая рамка вам нужна, я сделал в классе MyBitmap 2 метода: AddBorderOutside() и AddBorderInside().
    Я без понятия, скомпилируется ли код в C++ Builder, потому что я использовал Visual Studio.

    Код под спойлером
    #include <fstream>
    #include <ios>
    #include <ctime>
    #include <iostream>
    #include <windows.h>
    
    class MyBitmap {
        BITMAPFILEHEADER header_;
        BITMAPINFOHEADER info_;
        bool loaded_;
        char* pixels_;
        size_t data_size_;
        size_t row_padded_;
    public:
        MyBitmap(const char* fileName) {
            loaded_ = false;
            pixels_ = 0;
            std::ifstream bmp(fileName, std::ios::binary);
            if (!bmp) {
                return;
            }
            bmp.read((char*)&header_, sizeof(header_));
            if (!bmp) {
                return;
            }
            if (header_.bfType != 'MB') {
                std::cout << "Format is not supported" << std::endl;
                return;
            }
            bmp.read((char*)&info_, sizeof(info_));
    
            if (!bmp) {
                return;
            }
    
            if (info_.biBitCount != 24) {
                std::cout << "Format is not supported" << std::endl;
                return;
            };
    
            row_padded_ = (info_.biWidth * 3 + 3) & (~3);
            int height = info_.biHeight; 
            data_size_ = row_padded_ * height;
            pixels_ = new char[data_size_];
            bmp.read(pixels_, data_size_);
    
            if (bmp) {
                loaded_ = true;
            }
            return;
        }
    
        bool Save(const char* fileName) {
            if (!loaded_) {
                return false;
            }
            std::ofstream f(fileName, std::ios::binary);
            
            if (!f) {
                return false;
            }
            f.write((char*)&header_, sizeof(header_));
            f.write((char*)&info_, sizeof(info_));
            f.write(pixels_, data_size_);
            if (f) {
                return true;
            }
            return false;
        }
    
        void AddBorderInside(int borderSize = 15) {
            for (int i = 0; i < info_.biWidth; i++) {
                for (int j = 0; j < info_.biHeight; j++) {
                    if (i < borderSize || i >= info_.biWidth - borderSize 
                        || j < borderSize || j >= info_.biHeight - borderSize) {
                        int pos = row_padded_* j + i * 3;
                        pixels_[pos] = rand() % 256;
                        pixels_[pos + 1] = rand() % 256;
                        pixels_[pos + 2] = rand() % 256;
                    }
                }
            }
        }
    
        void AddBorderOutside(int borderSize = 15) {
            int new_width = info_.biWidth + borderSize * 2;
            int new_row_padded = (new_width * 3 + 3) & (~3);
            int new_height = info_.biHeight + borderSize * 2;
            int new_data_size = new_row_padded * new_height;
    
            char* new_pixels_ = new char[new_data_size];
            for (int i = 0; i < info_.biHeight; i++) {
                int old_pos = row_padded_* i;
                int new_pos = new_row_padded * (borderSize+i) +3 * borderSize;
                memcpy(new_pixels_ + new_pos, pixels_ + old_pos, info_.biWidth * 3);
            }
    
            delete[] pixels_;
            info_.biWidth = new_width;
            info_.biHeight = new_height;
            pixels_ = new_pixels_;
            row_padded_ = new_row_padded;
            data_size_ = new_data_size;
            AddBorderInside(borderSize);
        }
    
        bool IsLoaded() const {
            return loaded_;
        }
    
        ~MyBitmap() {
            delete[] pixels_;
        }
    
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        srand(time(0));
        MyBitmap bmp("input.bmp");
    
        if (!bmp.IsLoaded()) {
            std::cout << "Unable to load bitmap" << std::endl;
            return 1;
        }
        bmp.AddBorderOutside();
        if (!bmp.Save("output.bmp")) {
            std::cout << "Unable to save bitmap" << std::endl;
        }
    	return 0;
    }
    Ответ написан
    Комментировать
  • Сколько парадигм можно использовать одновременно при написании кода?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Так, ну поехали тогда примерно с начала.

    Парадигма программирования - это набор довольно строгих правил, определяющих способ организации вычислительных процессов программы.
    В целом, парадигма (para (греч.) - около; digma (греч.) - проба, образец) - это форма некоторой концепции, изложенная в виде формальных правил.

    Вот для примера несколько парадигм программирования, которые поддерживает язык C++:


    Реализация кода программы средствами современного C++ становится значительно легче, за счет усложнения самого кода, благодаря совместному использованию различных парадигм программирования. Часть кода незачем исполнять в ООП стиле, часть кода более удобна в виде шаблонов функций или классов, а часть кода незачем стараться делать вне ООП парадигмы.
    Ответ написан
    Комментировать
  • Что такое макросы в С++?

    32bit_me
    @32bit_me
    Программист, встраиваемые системы
    #define sqr(x) x*x - это образец того, как не нужно писать макросы.

    Более правильно так:

    #define SQR(x) ((x)*(x))

    Тогда:
    ((3+0)*(3+0)) = 9

    Но в С++ использование макросов считается дурным тоном (чаще всего). Используйте inline - функции.
    Ответ написан
    Комментировать
  • Что такое макросы в С++?

    myjcom
    @myjcom Куратор тега C++
    потому что x это 3 + 0; (целиком) это тупо текст, который будет вставлен вместо x;
    x * x == 3 + 0 * 3 + 0;

    получаем

    3 + (0 * 3) + 0;
    3 + 0 + 0;
    3;

    макросы в С++

    Атавизм
    иногда полезный
    https://en.cppreference.com/w/cpp/preprocessor/replace

    а так тут есть как минимум
    https://en.cppreference.com/w/cpp/language/constexpr
    https://en.cppreference.com/w/cpp/language/templates

    code
    #include <iostream>
    
    template<typename T>
    auto sqr = [](T x)
    {
      return x * x;
    };
    
    int main()
    {
      std::cout << sqr<int>(3 + 0);
    }


    что будет развернуто в что-то типа
    //...
    class __lambda_3_12
    {
      public: inline int operator()(int x) const
      {
        return x * x;
      }
    //...
    };
    //...

    Ответ написан
    Комментировать
  • Что такое токен на Github?

    ukko
    @ukko
    php, js (es6), golang, symfony, react
    Токен гарантирует что вы это вы. При этом пароль от GitHub вводить в других местах не нужно. Прочитайте подробнее про OAuth2.0
    Ответ написан
    2 комментария
  • Как создать токен на GitHub, какие пункты нужно отметить?

    pOmelchenko
    @pOmelchenko
    php-developer
    Ответ написан
    Комментировать
  • Как к четырем элементам массива добавить ещё два?

    SerJook
    @SerJook
    кодер
    Используйте std::vector.

    #include <iostream>
    #include <conio.h>
    #include <vector>
    using namespace std;
    
    int main()
    {
        int rez;
        int arr_src[] = {1,8,3,2};
        std::vector<int> arr(arr_src, arr_src + sizeof(arr_src)/sizeof(arr_src[0]));
    
        arr.push_back(7);
        arr.push_back(8);
    
        rez = arr.size();          //кол-во элементов в массиве
        cout << rez << endl;
    
        for (int i = 0; i < rez; i++)
            cout << arr[i] << ' ';
    
        getch();
        return 0;
    }


    Еще у вас ошибка в условии выхода из цикла.
    Ответ написан
    Комментировать
  • Как к четырем элементам массива добавить ещё два?

    @Mercury13
    Программист на «си с крестами» и не только
    Нужен или массив с запасом (например, на 6 мест), или динамический (например, std::vector).
    Си++ — язык достаточно низкого уровня, и сам программист видит, где там память динамически выделяется, а где выделена заранее.
    Ответ написан
    2 комментария
  • Какова роль указателей в сложных структурах данных?

    @pestunov
    1. Указатели позволяют осуществлять динамическое распределение памяти, что дает возможность задавать размер массива в процессе работы программы. Классический массив в качестве размера принимает только константу, требующую инициализации в коде, т.е. перед запуском программы.

    2. Указатели позволяют передавать массивы в качестве аргументов в функции без необходимости их копирования. Вообще, имя массива - это указатель на его первый элемент.

    Хотя в твоем коде можно было бы обойтись и без указателей. Особого эффекта они не дают. Размер массива у тебя постоянный.

    Во многих более новых (по сравнению с Си) языках, таких как Java, C# и пр. работа с указателями вообще закрыта, но технологически почти все делается через них (см. "ссылочные типы").
    Ответ написан
    1 комментарий
  • Как посчитать количество элементов в массиве?

    livevasiliy
    @livevasiliy
    Junior C++,Python 3
    Можно вот так немного перестать под 11-ый стандарт
    #include < array > // удали пробелы
    using namespace std;

    array i_arr;
    cout << "i_arr size: " << i_arr.size() << endl
    Ответ написан
    Комментировать
  • Как посчитать количество элементов в массиве?

    vt4a2h
    @vt4a2h Куратор тега C++
    Senior software engineer (C++/Qt/boost)
    std::size(mas)
    или
    std::distance(std::begin(mass), std::end(mass))

    Но лучше std::array использовать вообще. У него есть метод size.
    Ответ написан
    3 комментария
  • Где в отладчике отображается, что в этой программе максимальный элемент массива равен 9?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему у меня при отладке (картинка 1), и при чужой отладке (картинка 2) в сегменте, внизу, где четыре строки es, значения совершенно отличаются, хотя это отладка одной и той же программы?

    Мария, потому что память заполнена по большому счёту мусором. es в твоей программе не инициализирован, непонятно зачем ты на него смотришь. Надо смотреть на ds. В твоём отладчике Max находится по адресу 57ef:000a
    Ответ написан
  • Массивы. Как доработать код программы?

    usdglander
    @usdglander
    Yipee-ki-yay
    TITLE Prog3_2a 		;название программы
    .MODEL small 		;отводим под стек и под данные по 64Кб
    .STACK 100h 		        ;отмечаем начало сегмента стека
    .DATA 			        ;отмечаем начало сегмента данных
    A DW -5, 3, 9, -4, 5	        ;описание массива из 5 элементов
    
            
    .CODE 			        ;отмечаем начало сегмента кодов
    main PROC 	
    mov AX, @data 		;копируем адрес 
    mov DS, AX 		        ;сегмента данных
    mov SI, OFFSET A	        ;заносим в SI начало массива А
    mov CX, 4 		        ;в СХ заносим количество итераций
    cld 			               ;устанавливаем прямой порядок обработки массива
    mov AX, [SI] 	
    xor BX, BX
    
    L3:			
    and AX, 8000h
    cmp AX, 8000h
    jnz L2			         ;проверка на знак, если отриц. то 
    mov AX, 0
    mov [SI], AX
    inc BX
    
    L2: 			
    inc SI 			           ;сдвигаемся по массиву к следующему 
    inc SI 			           ;элементу
    mov AX,[SI] 		           ;заносим в АХ текущий элемент массива
    
    loop L3			           ;циклически повторяем все действия
    
    ;Тут в BX - количество положительных элементов массива (если 0 считать положительным)
    
    mov AX,4C00h 	    	   ;выход 
    int 21h 		                   ;из программы
    main ENDP 	
    END main
    Ответ написан
    5 комментариев
  • Какую литературу посоветуете для изучения математического анализа?

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

    Берите книгу "Письменный - Конспект лекций по высшей математике". Там вышка для тех. вузов - самое оно. А к ней задачники "Лунгу - Сборник задач по высшей математике, 1 курс" и "Лунгу - Сборник задач по высшей математике - 2 курс".

    Хорошее у Вас увлечение. Главное -- не перегорите.
    Ответ написан
    6 комментариев
  • Как найти значение этого математического выражения?

    32bit_me
    @32bit_me
    Программист, встраиваемые системы
    как-то так:
    int foo(int n)
    {
    int sign =1;
    int sum = 0;
    for(int i = 0; i <= n; i++)
    {
      sum += sign * (2 * i + 1);
      sign *= -1;
    }
    return sum;
    }
    Ответ написан
    9 комментариев
  • Компиляция в tasm. Как через Far Manager создать файлы .bat и .lst?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Shift+F4 - создать/редактировать файл. Вводите имя a.bat, откроется окно редактора, там набираете текст.
    lst-файл создастся автоматически при компиляции.
    Ответ написан
    1 комментарий
  • Ассемблер для начинающего?

    Dit81
    @Dit81
    Security researcher, pentester, internet-marketer
    Была такая подборка и даже книга Калашникова... Вот она просто для абсолютных новичков в Ассемблере. Там все азы были. А дальше только справочники по вызовам и прерываниям... Еще советую книгу «Хакинг. Искусство эксплойта» автора Джон Эриксон, там тоже с азов и ассемблера...
    Ответ написан
    1 комментарий
  • Как разобраться, что происходит в этом заголовочном файле?

    @Mercury13
    Программист на «си с крестами» и не только
    Учи понятие «единица компиляции». Тут, к сожалению, есть и вещи, которые должны быть в CPP-файле, и вещи, которые должны быть в H-файле.

    #pragma pack(1)
    Структуры данных нам нужны «один в один», без байтов заполнения.

    struct FileHeader 
    struct MAPINFO

    Формат BMP. Не забывай, что формат BMP записывается с нижней строки!

    Функция Open читает картинку «один в один», Save пишет «один в один», GetMapInfo и GetFH выдают какие-то заголовки нашего BMP.

    Остаётся GetMap(), который, по идее, должен выдавать матрицу цветов, но реально действует только для 32-битного BMP и никак не инкапсулирует ни ширину-высоту матрицы, ни тот факт, что формат BMP пишется с нижней строки.

    За этот код — тройка с минусом.

    А теперь чего ваш код НЕ поддерживает, но, по идее, должен, чтобы выполнить вашу задачу.
    1. Создание BMP нужного размера с нуля, а не загрузка из файла.
    2. Инкапсулировать матрицу пикселей. Желательно так, чтобы был быстрый доступ к строкам как к буферам в памяти, для простоты переноса информации из старого BMP в новый, на 30×30 пикселей больший.
    3. Если вы ограниченно поддерживаете формат BMP — вылетать с ошибкой, если версия неподдерживаемая (например, не то количество цветов).

    Задача именно своими силами наладить поддержку BMP? А то в Builder’е есть TBitmap.
    Ответ написан
    6 комментариев
  • Какой лучший курс по c++?

    alex4answ
    @alex4answ
    На stepik есть очень хорошие,
    Сначала введение от академии Яндекса пройдите
    Затем 2 курса от Александра Смаль
    Ответ написан
    Комментировать