Задать вопрос
  • Как решать задачу, пожалуйста?

    wataru
    @wataru Куратор тега Математика
    Alexandroppolus, Технически, вы правы. Но я думаю, что этот ответ бы никак не зачли, ибо в условии подразумевается хотя бы 5 студентов. Просто составители не подумали про это.
    Написано
  • Как решать задачу, пожалуйста?

    wataru
    @wataru Куратор тега Математика
    Максим Короткевич, Не мог второй найти тот же интеграл. Потому что этот тот интеграл, которого не хватало, когда мы первого исключили. Это тот интеграл, который взял первый и никто другой.

    Вот формально: пусть T1..T5 - множества интегралов, которые взяли 1-5 чуваки. Дано T1 U T2.. U T5 = I - множество всех интегралов.

    Мы взяли i1 = Any(T1 / (T2 U T3 U T4 U T5)) - любой из интегралов, который есть в первом, но его нет у всех остальных. i2 = Any(T2 / (T1 U T3 U T4 U T5)) - любой из интегралов, который есть во втором, но его нет у всех остальных. и так далее.

    i1 есть в T1, но его нет в T2. i2 есть в T2, но его нет в T1. Они не могут совпадать по определению.
    Написано
  • Reinterpret_cast вектора типа double в T неопределенное или определенное поведение?

    wataru
    @wataru Куратор тега C++
    Dyikot, Да. Нельзя Time читать как double. все та же фигня со strict aliasing. Придется копировать в double, или делать шаблоны, или делать виртуальный метод GetDoubleData() у всех структур. Но тогда тупо double в функцию уже не передать.

    Еще можно всю вашу архитектуру перелопатить с массива структур на структуру массивов. Так даже быстрее будет.
    Написано
  • Заголовочные файлы в Си нужны только для интерфейса?

    wataru
    @wataru Куратор тега C++
    AslanPAPA,
    странно когда говорят, компилятору достаточно того что он знает тип функции и параметры, а то что она делает не важно ?


    Тут бы помогло знание ассемблера и того как работают процессоры. Идея такая: чтобы вызвать функцию, компилятору надо сгенерировать код, который параметры и адрес возврата положит в нужное место (стек), а потом перейдет в код функции. Код функции берет параметры из стека, выполняется,а потом возвращает исполнение в место вызова. Тело функции не знает, где оно будет вызвано, оно отдельно где-то есть, ему важно только что вызывающий код правильно положит в стек параметры. Чтобы это правильно сделать надо лишь знать сигнатуру функции - сколько и каких у нее параметров и что она возвращает. Ну и имя, конечно, чтобы знать, что вообще вызывать.

    Вы не путайте: объявление - это имя и параметры функции. Определение - тело. Для вызова функции надо знать ее объявление. В итоговой программе каждая используемая функция должна быть еще и определена. Возможно в другом файле.

    Ну хорошо нужны эти определения, так давайте я их определю в самом math_fanctions.c. И все компилятор будет знать определения функций?


    Если вы имеете ввиду объявления, то нет. Компилятор компилирует каждый .c файл отдельно. Он вообще ничего не знает о других .c файлах. Поэтому объявление функций должно как-то попасть в Main.c. Они записаны в хедерах, которые вы включаете в main.c файл и все работает.

    Что-то типа плохо включать через #include "math_function.c" нужно именно ".h" или что?


    Дело в том, что определение - тело - у функции может быть только одно. Теоретически вы можете включить math_function.c в main.c и скомпилировать только main.c. И все даже сработает в этом простейшем случае. Но если у вас в проекте несколько разных файлов, использующих math_function.c у вас опредения функций появятся в разных обхъектных файлах и линкер выдаст ошибку. Компилятор при этом даже все скомпилирует, но исполнительный файл вы собрать не сможете. Теоретически всякими прагмами once и очень аккуратной расстановкой можно даже заставить сложные проекты заработать, но у вас может все сломаться. Вот есть файл a.c он использует функции из b.c. А b.c использует из a.c. Что куда включать и как?

    Вторая причина никогда не включать никуда .c файлы - это скорость компиляции. Когда у вас определение функции в отдельной единице трансляции (.с файле) и компилируется отдельно, у вас тело скомпилируется ровно один раз. Если же оно включается в кучу файло, оно будет компилировано в каждом файле. Потом, если вы измените код функции не меняя ее сигнатуру, вам можно не перекомпилировать main.c. Код там только лишь вызывает функцию, он не содержит ее тело. Можно взять уже готовый объектный файл main.o и слинковать его с обновленным math_functions.o.
    Написано
  • Заголовочные файлы в Си нужны только для интерфейса?

    wataru
    @wataru Куратор тега C++
    AslanPAPA,
    Но зачем если ей известно уже вся функция и заголовок и тело. Или это просто так надо ?


    Вот в примере выше компилятору известно. А если функция в другом файле - то нет. Компилятор, когда комплиирует main.c вообще ничего не знает про файл math_function.c. В Си каждый файл компилируется отдельно независимо от остальных, создает объектый файл. Уже потом линкер из нескольких объектных файлов собирает один исполнительный.

    Если же в примере выше функцию sqr определить после main, то это не сработает, потому что компилятор читает файл сверху вниз. И, наткнувшись на вызов функции sqr, он еще про саму функцию ничего не знает. Если же сначала объявить что такая функция есть и какие у нее параметры выше, то компилятору этого достаточно. В месте вызова sqr в main компилятору не важно, что там внутри функции, ему важна лишь сигнатура, и он ее уже знает.
    Написано
  • Заголовочные файлы в Си нужны только для интерфейса?

    wataru
    @wataru Куратор тега C++
    AslanPAPA, Можно сразу написать определение сверху, не надо объявлений:

    #include <stdio.h>
    
    double sqr(double a)
    {
           return a*a;
    }
    int main(void)
    {
         return 0;
    }


    В современном стандарте определение функции является сразу и объявлением. Но оно должно быть раньше первого использования функции, чтобы компилятор знал как функцию вызывать, какие у нее параметры и что она возвращает.

    Но, если у вас тело sqr в другой единице трансляции, то без объявления никак.
    Написано
  • Как правильно реализовать блок памяти для сильной и слабой ссылки?

    wataru
    @wataru Куратор тега C++
    Dyikot, Вообще, да, для union'ов деструкторы тоже не будут вызываться.
    Но мне больше нравится reinterpret_cast, потому что union с одним значением выглядит диковато. И вообще, это использование не по назначению ради побочных эффектов.

    Вам надо выделить память, но не вызывать у нее деструктор. Отдельный массив тут выглядит логичнее. Хотя это вксовщина.
    Написано
  • Как правильно реализовать блок памяти для сильной и слабой ссылки?

    wataru
    @wataru Куратор тега C++
    Dyikot, Проблема при копировании, сначала написал не ответ, а комментарий, но ссылка пострадала в процессе переноса. Вот корректная ссылка: https://chromium.googlesource.com/chromium/src/bas...

    Идея в том, что вместо члена класса T, в заводите массив char[sizeof(T)], и делаете reinterpret_cast при работе с ним. В этом случае деструктор и конструктор не будут автоматически вызываться, их надо вызывать вручную, когда вам надо.
    Написано
  • Как узнать, хранятся числа в компьютере в прямом, дополнительном или обратном коде?

    wataru
    @wataru Куратор тега C++
    Евгений Шатунов, Ну я же сказал, что нельзя обращаться по указателю другого типа. Ключевое слово алиасинг людей только запутает.
    Написано
  • Как узнать, хранятся числа в компьютере в прямом, дополнительном или обратном коде?

    wataru
    @wataru Куратор тега C++
    res2001, Опять же, в случае signed/unsigned одного и того же типа - это не UB. В противном случае, там нарушение правила strict aliasing и это UB.
    Написано
  • Имя массива это адрес первого элемента или указатель на его первый элемент в Си?

    wataru
    @wataru Куратор тега C++
    AslHack, Вы путались вот тут:
    zippo[0] это адрес первого элемента в подмассиве ({2, 4}) т.е 2
    .

    Понятнее было бы с zippo[1]. zippo - это массив из строк. Значит zippo[1] - это вторая строка. Но строка -массив, а значит фактически это указатель на первый элемент второй строки.
    zippo[0] - это адрес строки {2,4}. Да, он совпадает с адресом 2, потому что 2 лежит в строке в начале. Но это совпадение. У вас могла бы быть не строка, а какая-нибудь хитрая структура.

    zippo - Это двумерный массив, те. фактически указател-на-указатель. Каждые [] и * уменьшают указательность. Каждые & - увеличивают.
    Написано
  • Имя массива это адрес первого элемента или указатель на его первый элемент в Си?

    wataru
    @wataru Куратор тега C++
    > ещё почему-то я думаю что это так же адрес первого элемента первого подмассива (первой строки) т.е 2)

    А адреса совпадают. Ведь строка в памяти идет подряд и указатель на начало строки - хранит тот же адрес, что и указатель на первый элемент второй строки. Но надо помнить, что у него тип "указаель на массив". Соответственно, адрессная арифметика будет при +1 прибавлять размер строки, а не одного элемента.

    Вы путаетесь, zippo - это указатель на int[2]. Адрес первой строки. zippo[0] - это взять первый элемент массива, т.е. строку. Т.е. вы получили указатель на первый элемент строки. Чтобы получить двойку надо этот указатель разименовать дописав [0]. Еще можно было бы сделать **zippo.

    Но, чтобы получать элемент вам лучше индексировать массив. zippo[1][1] - второй элемент во второй строке. zippo[0][0] - это двойка. Не надо пытаться в адрессную арифметику и прибавлять числа к zippo или *zippo. Запутаетесь только и пользы никакой не извлечете.
    Написано
  • Имя массива это адрес первого элемента или указатель на его первый элемент в Си?

    wataru
    @wataru Куратор тега C++
    jcmvbkbc, А вот в этой программе - одинаковый:
    #include <stdio.h>
    int main()
    {
        int a[4] = {1,2,3,4};
        int *p = (int*)&p;
    
        printf("%p, %p\n", a, &a);
        printf("%p, %p\n", p, &p);
    }


    Каждая переменная выводит свой адрес два раза.

    А вот в этой программе a1 и a2 выводят разное, это значит по вашему, что эти 2 указателья ведут себя по разному?
    #include <stdio.h>
    int main()
    {
        int *a1 = (int*)&a1;
        int *a2 = a1;
    
        printf("%p, %p\n", a1, &a1);
        printf("%p, %p\n", a2, &a2);
    }


    Да, он не совсем идентичен указателю. Наверное я не очень точно выразился. Но оно к нему приводится во многих контекстах.
    Написано
  • Правильное ли док-во существования функции?

    wataru
    @wataru Куратор тега Математика
    floppa322, f(x)-f(0)=2x => f(x) = 2x+f(0). f(0) - какое-то число, константа. f(x) = 2x+C.

    не надо рассуждать про разности с произвольной точкой, просто вот мы получили формулу для f(x).
    Написано
  • Правильное ли док-во существования функции?

    wataru
    @wataru Куратор тега Математика
    floppa322, f(x)-f(0)=2x => f(x) = 2x+C

    Т.е. следует, что функция - прямая. Других нет, потому что они - не прямые. А мы уже знаем, что это прямая.
    Написано
  • Как понять что переполняет память в C++?

    wataru
    @wataru Куратор тега C++
    Похоже, нельзя удалять bitmap, когда хендл из него не удален. Что-то внутри течет.
    Написано
  • Как понять что переполняет память в C++?

    wataru
    @wataru Куратор тега C++
    Попробуйте bitmap и hbitmap уничтожать вместе. Сначала hbitmap, потом bitmap.

    Из функции возвращайте bitmap, получайте hbitmap на месте и после использования удаляйте.
    Написано
  • Как понять что переполняет память в C++?

    wataru
    @wataru Куратор тега C++
    Андрей Вшивков, Если GdiplusStartup вынести за цикл, оно все еще течет?
    Написано
  • Как понять что переполняет память в C++?

    wataru
    @wataru Куратор тега C++

    Каким-нибудь process explorer можно посмотреть сколько хендлов ваша программа имеет, если это число растет, надо разбираться, какие из виндовых объектов вы правильно не уничтожаете. Вроде бы все битмапы вы корректно уничтожаете через DeleteObject, возможно ошибка в другом коде.

    Можно еще поробовать вашу программу подебажить. Вот когда окно вылезает, какой ваш код выполняется? Подключитесь к вашему процессу visual studio и смотрите. Или добавьте отладочный вывод, чтобы понять, какая функция начинает выполнятся но не заканчивает. Это подскажет вам, какие объекты вы не удалили правильно.
    Написано
  • Как понять что переполняет память в C++?

    wataru
    @wataru Куратор тега C++
    Андрей Вшивков, Ну это вот эти хендлы небось и есть. И проблема не втом, что вся память утекла и кончилась, а у операционки закончились хендлы.
    Написано