Ответы пользователя по тегу C++
  • Алгоритм поворота динамического массива без доп памяти?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как можно реализовать, поворот динамического массива (матрица), без доп памяти?

    Как-то так:

    #include <stddef.h>
    #include <stdio.h>
    
    typedef int T;
    
    void rotate(T *p, size_t m, size_t n, size_t (*turn)(size_t m, size_t n, size_t idx))
    {
            size_t i, j, k;
    
            for (i = 0; i < m * n; ++i) {
                    T tmp0, tmp1;
    
                    for (j = 0; j < i; ++j) {
                            for (k = turn(m, n, j); k != i && k != j; k = turn(m, n, k)) {
                            }
                            if (k == i)
                                    break;
                    }
                    if (j < i)
                            continue;
    
                    tmp0 = p[i];
                    for (j = turn(m, n, i); ; j = turn(m, n, j)) {
                            tmp1 = p[j];
                            p[j] = tmp0;
                            tmp0 = tmp1;
                            if (j == i)
                                    break;
                    }
            }
    }
    
    void dump(size_t m, size_t n, T p[m][n])
    {
            size_t i, j;
    
            for (i = 0; i < m; ++i)
                    for (j = 0; j < n; ++j)
                            printf("%d%s", p[i][j], j == n - 1 ? "\n" : ", ");
    }
    
    size_t turn_ccw(size_t m, size_t n, size_t idx)
    {
            return (n - 1 - idx % n) * m + (idx / n);
    }
    
    size_t turn_cw(size_t m, size_t n, size_t idx)
    {
            return (idx % n) * m + m - 1 - (idx / n);
    }
    
    #define M 5
    #define N 7
    
    int main()
    {
            size_t i, j;
            T a[M][N];
    
            for (i = 0; i < M; ++i)
                    for (j = 0; j < N; ++j)
                            a[i][j] = i * N + j;
    
            rotate(&a[0][0], M, N, turn_ccw);
            dump(N, M, (T (*)[M])&a[0][0]);
            printf("\n");
            rotate(&a[0][0], N, M, turn_cw);
            dump(M, N, (T (*)[N])&a[0][0]);
    }


    turn преобразует линейный индекс элемента из оригинального массива в индекс элемента в повёрнутом массиве.
    Цикл по i переставляет цепочки элементов отображающихся друг в друга с началом в элементе i. Первый цикл по j проверяет, не был ли элемент i уже переставлен в составе более ранней цепочки. Второй цикл по j переставляет одну цепочку.
    Ответ написан
    Комментировать
  • Почему и как этот код на Си работает, если он работать не должен?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    но почему, если мы его занулили в самом начале программы?

    int i,k,w = 0;

    Сюрприз №1: в этой строке мы занулили только w (да и то непонятно зачем).

    // каким образом i учавствует в коде, если мы с ней
    // ничего не делали?? если убрать это условие, код не работает

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

    Сюрприз №2: вот же, i++, какое "ничего"?

    зачем в этом коде нужна переменная k,

    Переменная k в этом коде не нужна, если не считать единственного printf с её участием.

    Как это код работает?

    Разбивает исходную строку по пробелам тут: ptr=strtok(s," ");, в цикле for(i=0; i<w; i++) проверяет, что подстрока состоит только из символов 'a'..'z', если да (т.е. i в цикле достиг длины текущей подстроки) -- печатает подстроку. Переходит к следующей подстроке тут: ptr=strtok(NULL," ");
    Ответ написан
  • C++ Builder. Аналог REG DELETE в CMD. Как удалить ветку реестра?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    AnsiString params[] = {"/c REG DELETE \"***\"};
            for (unsigned short i = 0; i < params->Length(); {
               system(params[i].c_str());
            }

    ругается на "Access violation at address"

    Потому что этот код думает, что длина первой строки -- это количество строк в массиве params. С чего бы?
    Ответ написан
    Комментировать
  • Как правильно решить задачу на работу с двумя массивами в asm?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Нужно из c++ переместить этот массив в ассемблерную вставку, а там уже перенести из этого массива в другой массив все элементы, которые равны сумме соседних.
    То есть регистры e*x нельзя брать. Кто может подсказать, где найти материал по этой теме, либо же предложить пример кода для решения поставленной задачи?

    Можно написать этот код так, что он не будет использовать никакие конкретные регистры явно. Конкретные регистры будут подставлены компилятором. Например (gcc):
    #include <stdint.h>
    
    void f(void)
    {
        uint32_t a[16] = {1, 2, 3, 1, 5, 4, -1, }, b[16] = {0};
        void *a1, *b1;
        uint32_t tmp, cnt = 14;
    
        asm (
            "lea %[a], %[a1]\n\t"
            "lea %[b], %[b1]\n"
            "1:\n\t"
            "mov (%[a1]), %[tmp]\n\t"
            "add 8(%[a1]), %[tmp]\n\t"
            "cmp 4(%[a1]), %[tmp]\n\t"
            "jne 2f\n\t"
            "mov %[tmp], (%[b1])\n\t"
            "add $4, %[b1]\n"
            "2:\n\t"
            "add $4, %[a1]\n\t"
            "dec %[cnt]\n\t"
            "jnz 1b\n\t"
            : [cnt] "=&r" (cnt), [tmp] "=&r" (tmp),
              [a1] "=&r" (a1), [b1] "=&r" (b1),
              [b] "=m" (b)
            : [a] "m" (a));
    }
    Ответ написан
  • Как вывести несколько MessageBox на C++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    MessageBox -- модальный. Невозможно одновременно вывести несколько MessageBox из одного потока. Можно создать несколько потоков и в каждом из них вызвать MessageBox.
    Ответ написан
    Комментировать
  • Почему не идентифицируется переменная NAN?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Предположу, что NAN появился в С++11, а VS12 его, вероятно, не поддерживает.
    Ну и, справдливости ради, определятся он в <cmath>, который неплохо было бы явно подключить.
    Ответ написан
    1 комментарий
  • Merge c типом string?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    if (arr[i] <= arr[j]) {
                d[k] = arr[i];
                da[k] = arr2[i];
                i++;
            } 
            else {
                d[k] = arr[j];
                da[k] = arr2[i];
                j++;
            }

    Тут какая-то совсем уж беда с индексами arr и arr2.

    std::string d[end - begin];
        std::string da[end - begin];


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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как ускорить работу этого потока чтоб он использовал все ресурсы процессора?

    Повышение приоритета не ускорит работу потока который занимается вычислениями, но понизит отзывчивость всех остальных потоков.
    Чтобы ускорить нужно сначала понять что именно тормозит, а чтобы это понять нужно профилировать.
    А уж когда станет понятно -- тогда и думать, что делать -- менять алгоритм, распараллеливать, использовать SIMD или что-нибудь ещё.
    Ответ написан
    3 комментария
  • Как правильно добавить в программу считывание количества объектов класса с помощью статического поля?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    постоянно 0 показывает

    Потому что в одном конструкторе ты matr::m_id инициализировал, а в другом -- нет.
    Ответ написан
  • Как передать указатель на двухмерный массив?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    https://toster.ru/answer?answer_id=513953#answers_... , за исключением части касающейся С99.
    Ответ написан
  • Наследование. Каким образом вызывается operator=() через оператор разрешения контекста?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Ведь operator=() - не статический метод, а значит его вызывать можно только через объект.

    Если делать это внутри другого не-статического метода, то можно, объектом будет *this.
    Ответ написан
    1 комментарий
  • Я человек не очень понимающий. Скажите пожалуйста что я не так сделал ( программа вылетает при работе)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    что я не так сделал?

    Как минимум вот это:
    double** a = new double *[n];
      int min;
      for (int k = 0; k < n; ++k)
      {
        for (int j = 0; j < n; ++j)
        {
          cout << "Enter element:";
          cin >> &a[k][j]);
        }
      }

    Ты представил матрицу как массив указателей на строки, выделил память под этот массив, но не выделил память под сами строки.
    Ответ написан
  • Как запустить приложение через forkpty?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    может быть так?

    #include <pty.h>
    #include <unistd.h>
    #include <thread>
    #include <future>
    #include <iostream>
    #include <string>
    
    ssize_t sz = 1;
    
    int main()
    {
      int mfd;
    
      pid_t pid_fork = forkpty(&mfd, NULL, NULL, NULL);
    
      if (!pid_fork) {
        // Дочерний процесс
        execl("/bin/sh", "-", NULL);
      } else {
        // Родительский процесс
        char buf[1024];
    
        // Async
        auto future = std::async(std::launch::async, [mfd]() {
          std::string line;
          while (sz) {
            std::getline(std::cin, line);
            line = line  + "\n";
            write(mfd, line.c_str(), line.size()); // Нужно направить в дочерний процесс как stdin
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
          }
        });
    
        while (sz = read(mfd, buf, sizeof(buf))) {
          write(STDOUT_FILENO, buf, sz); // Вывод из дочернего процесса stdout
          std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    
        exit(0);
      }
    }

    Поскольку это теперь терминал, то имеет смысл установить размеры pty такими же, как у терминала вызывающей программы, например так:

    ...
    #include <sys/ioctl.h>
    ...
      struct winsize ws, *pws = NULL;
    
      if (ioctl(1, TIOCGWINSZ, &ws) >= 0)
        pws = &ws;
      pid_t pid_fork = forkpty(&mfd, NULL, NULL, pws);


    Кроме того, sleep_for в циклах чтения и записи не нужен, поскольку операции чтения присутствующие в обоих циклах -- блокирующие. Но нужна проверка того, что записались все прочитанные данные.
    Ответ написан
    1 комментарий
  • Как сделать массив произвольной длины?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как быть? Какой размер массива объявить?

    Не объявляй никакой. Воспользуйся вместо этого стандартным контейнером, например std::vector.
    Но если хочется помучаться -- воспользуйся указателем и выделяй память динамически, по мере поступления входных данных.
    Ответ написан
    Комментировать
  • Множественный вызов конструктора базового класса при виртуальном наследовании?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    напрашивается вопрос "Будет ли конструктор базового класса A вызываться два раза, ведь в конструкторе C тоже вызывается конструктор A?".


    Нет, не будет, потому что нет, при конструировании объекта класса D конструктор A из конструктора C не вызывается. См.:
    A mem-initializer where the mem-initializer-id denotes a virtual base class is ignored during execution of a constructor of any class that is not the most derived class.
    Ответ написан
    Комментировать
  • Почему данные не записываются в реестр?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    LONG error = RegCreateKeyEx(...);
      if (hKey) {

    Ошибок нет, но и результатов нет !

    Ошибок нет, потому что ты не проверяешь код ошибки, а вместо этого проверяешь hKey.
    Если внимательно прочитать https://docs.microsoft.com/en-us/windows/win32/sys... то можно увидеть для KEY_WOW64_32KEY, что
    This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.

    Подозреваю, что там должно быть KEY_WOW64_32KEY | KEY_SET_VALUE.

    RegSetValueA(hKey, "test", REG_SZ, (LPCSTR)path.c_str(), sizeof(path.c_str()));

    Не sizeof. И код ошибки тоже не проверяешь.
    Ответ написан
  • Как хранятся числа в памяти?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    struct Data {
      short id;
      double val;
    };


    я понимаю что 32 00 11 49 - это интовское значение

    в этой структуре short int, 2 байта. 0x32 0x00 -- это оно (0x32 + 256 * 0x00 = 50), little endian.
    0x11 0x49 -- это мусор. 0x02 0x56 0x00 0x00 идущие дальше -- это тоже мусор.
    0x33 0x33 0x33 0x33 0x33 0x33 0xf3 0x3f -- это double (0x3ff -- порядок, 0x3333333333333 -- мантисса, значение = 0x1.3333333333333 * 2 ^ (0x3ff - 1023) = 1.19999999999999995559), little endian, ieee754.

    Как в данном выводе понять где выравнивание происходит?

    Можно воспользоваться макросом offsetof.
    Ответ написан
    5 комментариев
  • Как понять условие задачи?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я подумал, что граф всегда можно разбить на две множества так, чтобы вершины, соединенные максимальным ребром были в одном множестве, а остальные вершины в другом, то-есть ответом всегда будет максимальное ребро. Я протестировал свое решение в яндекс.контест и получил ошибку на 8 тесте. Подскажите пожалуйста, что я не правильно понял из условия?
    Может есть контрпример?

    Контрпример: квадрат, верхнее ребро -- 2, боковые -- 1, нижнее -- 0. В терминах входных данных для задачи:
    4 4
    0 1 2
    1 2 1
    2 3 0
    3 0 1

    Если разбивать твоим алгоритмом, то в одно множество попадают две верхние вершины, во второе -- две нижние. Тогда "ребро минимального веса, соединяющее вершины из одного множества" -- это ребро соединяющее две нижние вершины (2 3), его вес -- 0.
    Но если разбить граф на две левые вершины (3 0) и две правые (1 2), то "ребро минимального веса, соединяющее вершины из одного множества" имеет вес 1, что лучше, чем 0.
    Ответ написан
    Комментировать
  • Может ли процессор изменять порядок инструкций в программе?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Насчет компиляторов поверю, но вот процессора ??? как ???

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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В сети не нашёл ответа.

    В каждом из разделов стандарта касающихся операторов написано в каком порядке группируются вызовы опреаторов в однородных выражениях (например).

    Получается, что, если явно скобками не обозначить, то ассоциативность всегда будет справа налево, или я не прав?

    Почти все операторы группируются слева направо, за исключением префиксных операторов и операторов присваивания (в том числе составных).

    Пример

    #include <string>
    #include <iostream>
    
    struct A
    {
            std::string name;
    
            A(const std::string& _name): name(_name)
            {
            }
    
            A operator +(const A& other) const
            {
                    std::cerr << name << " + " << other.name << std::endl;
                    return A(std::string("{temporary from ") + name + " + " + other.name + "}");
            }
    };
    
    int main()
    {
            A first("first"), second("second"), third("third");
            A r = first + second + third;
    }

    выводит
    first + second
    {temporary from first + second} + third
    Ответ написан
    Комментировать