Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по программированию на C/С++

Автор: BagaBaga
Дата сообщения: 04.10.2012 09:46
juvaforza,
спасибо. Об этом я не подумал (может, действительно кто захочет применить к такому указателю delete).

karakurt2,
Спасибо. Теперь я знаю, откуда у "метода" ноги растут. Хотя, наверняка, были и более ранние работы, но эта уж точно популяризировала этот метод.

Есть любопытный вопрос про выделение памяти с new.
Вроде как new должно порождать исключение, если выделить память не удалось (ну, или возвращать NULL-указатель при выделение памяти в С-стиле через nothrow).

Так вот, если запросить на 32-разрядной системе
new int [n]
где sizeof(int)*n>2Gb (на реальном примере я "неглядя" попросил больше 4),

то память "как бы" выделяется - ни исключения не порождается, ни NULL-указателя не выдаётся. Зато при попытках обращения (записи) уже в процессе выполнения происходит segmentation fault. Это нормальное поведение для new? Или же он должен был дать "отлуп"?
Автор: panda3
Дата сообщения: 04.10.2012 13:37
Думаю, тут нет ошибки.
new int [n] эквивалентно (int*)operator new[](n * sizeof(int));
аргумент operator new имеет тип size_t (32 бит).
Проблема переполнения при умножении в C++ - это проблема программиста, а не компилятора.
Если в компиляторе включена опция типа Smaller Type Check в MSVC, то ошибку можно словить, объявив n как unsigned long long (т.е. 64 бит).
Автор: BagaBaga
Дата сообщения: 05.10.2012 13:19
Вот такой вопрос. "Раньше" при выводе в консоль "выводили строчку", потом 21 прерыванием её убирали и "рисовали на ёё месте" новую, эмулируя таким способом, например, таймер или счётчик. Реально ли повторить этот финт с использованием стандартных потоков ввода-вывода (cin/cout)? Или что попало, то "не отменить"?
Автор: adasiko
Дата сообщения: 05.10.2012 16:04
BagaBaga
А если
cout << "1%";
cout << "\r2%";
Автор: BagaBaga
Дата сообщения: 05.10.2012 22:41
Оно
Автор: BagaBaga
Дата сообщения: 16.10.2012 16:37
Вот такой вопрос: не пойму, что произойдёт.
Есть функция, принимающая ссылку на vector, и возвращающая ссылку на vector.

vector& func(vector &vec){ return vec;}

Так вот, что будет, если вызов будет сделан таким образом:
vector &vv = func(vector(some)).
Т.е. в том случае, когда экземпляр вектора передаётся в функцию через анонимную временную переменную (вызов конструктора vector происходит внутри '()' )? vv будет невалидным?
Автор: panda3
Дата сообщения: 18.10.2012 12:12
Естественно, временный объект после вызова функции будет уничтожен, а у вас останется на него ссылка.
Автор: YuriyRR
Дата сообщения: 18.10.2012 13:35
BagaBaga

Цитата:
vector(some)

это никакой не вызов конструктора, а указание компилятору как воспринимать some. ничего не произойдет (
Автор: BagaBaga
Дата сообщения: 18.10.2012 23:17
Погоди-погоди.

std::vector <int> a; //объявляем вектор, вызывается конструктор по умолчанию
std::vector <int> b(3); // объявляем вектор с указанием его размера, элементы инициируются значением по умолчанию
std::vector <int> b(3,10); // объявляем вектор с указанием его размера, элементы инициируются значением 10
std::vector с(b); // объявляем вектор, инициируем его значением другого вектора, если я ничего не путаю, вызывается конструктор копирования. Тип для специализации шаблона можно вроде как не указывать, т.к. компилятор может его вывести из b. Но можно "для уверенности" и указать.

Теперь есть функция (для простоты пусть ничего не возвращает)
void func(std::vector<int>& tmp) {return;} //Допустим, что оптимизатор не заменит её "пустым местом".

Когда делается вызов
func(std::vector<int> (b))
происходит создание анонимной временной переменной, которая инициализируется вектором b, ссылка на которую и передаётся в функцию.

В принципе, можно сделать и без анонимной временной переменной, например
std::vector<int> tmp_vec(b);
func(tmp_vec);
Тогда эта переменная не станет анонимной (т.к. мы явно её декларируем. В прочем, в данном примере ничего не изменится, если использовать исходную переменную b, а не вводить некую новую временную). Но тогда и мой вопрос (исходный) теряем смысл, т.к. такой вызов законен в пределах видимости переменной tmp_vec. Весть вопрос де-факто сводится к области видимости (если угодно - времени жизни) анонимной временной переменной (создаваемой при вызове функции).
Автор: RoMiGoR
Дата сообщения: 20.10.2012 09:49
Такой вопрос, есть задача http://informatics.mccme.ru/moodle/mod/statements/view3.php?id=5552&chapterid=111274 с Московской командной олимпиады, есть решение с предподсчётом:

Код: #include <iostream>

using namespace std;

int main()
{
ios::sync_with_stdio(false);
long long Year[400] = {106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 106, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 105, 105, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104};
long long n, year; //
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> year;
cout << Year[year % 400] << endl;
}
return 0;
}
Автор: karakurt2
Дата сообщения: 20.10.2012 09:56
программы на С компилируются в гораздо более эффективный код, чем программы на С++, это уже давно замечено, хотя и противоречит тому, что пишут в книгах. с другой стороны, стоимость программирования на С обходится гораздо дороже.
Автор: akaGM
Дата сообщения: 20.10.2012 13:20
"С -- ассемблер со структурами данных" (с)
Автор: Olgaolikl
Дата сообщения: 20.10.2012 16:31
#include "stdafx.h"
#include <math.h>
#include <stdio.h>
#include <conio.h>

void main()
{
    ТИП a=1000, b=0.0001, k, l, m, n;

    k=(a+b)*(a+b); printf("%f\n", k);
    l=a*a; printf("%f\n", l);
    n=2*a*b; printf("%f\n", n);
    m=b*b; printf("%f\n", m);
    printf("a=1000, b=0.0001\n");
    printf("((a+b)^2-(a^2+2ab))/b^2=%f\n", (k-(l+n))/m);
    getch();
}

почему итоги программы при ТИПе float настолько значительно отличается от типа double? (в float значение равно приблизительно 1248994.243, а в double 1.001)
Автор: karakurt2
Дата сообщения: 20.10.2012 16:41
Olgaolikl
printf ничего не знает о типах
разбиритесь с форматной строкой
Автор: adasiko
Дата сообщения: 21.10.2012 07:46
RoMiGoR
Ну так потоки весьма сложная и непростая штука, в таких простеньких мини программах естественно c++ применять странно
Olgaolikl
переполнение при использовании хитрого вычисления с числами разного порядка. у типа float просто не хватает количества хранимых знаков
Автор: JustAMaaan
Дата сообщения: 21.10.2012 16:28
Скорее не переполнение, а потеря точности.
Автор: juvaforza
Дата сообщения: 21.10.2012 19:05
Olgaolikl
Если на пальцах, то в числителе вычитаются два числа порядка 10^6, а затем результат умножается на число порядка 10^8. Если точность одинарная, то абсолютная погрешность значения числителя будет порядка 10^(1+6-8). А если двойная, то порядка 10^(1+6-16). Т. е. значение числителя будет в первом случае порядка 10^(-1) (если сложить 10^(-8) и 10^(-1)), а втором - порядка 10^(-8) (если сложить 10^(-8) и 10^(-9)).

Можете проверить конкр. значения, распечатав каждую ариф. операцию.

P. S.
Точнее, если относительная погрешность числа равна 10^(-x), то для числа 10^y абсолютная погрешность равна 10^(y-x). И если для типа double показатель х~=15.9 взять не 15 (как выше, просто счет по-другому), а 16, то результат деления может быть ~=1.01 (т. е. более правдоподобно). Для типа float - x~=7.2.
Автор: Kars25rus
Дата сообщения: 21.10.2012 19:27
Доброго времени суток!

Краткая предыстория: на предмете компьютерная геометрия и графика раздали кучу страшных, как атомная война, лаб:

1. Написать программу для поворота отрезка прямой линии на произвольный угол относительно заданной точки.
2. Реализовать процедуру отсечения. В заданном окне 20-50 концентрических прямоугольников, смещенных друг относительно друга на произвольный угол и на &#61508;R с использование процедуры отсечения.
3. Реализовать рекуррентную процедуру. (Написать вариант программы дерево Пифагора (нерегулярная версия)).
4. Написать программу, генерирующую полигон произвольной формы с n-вершинами (n=100).
5. Написать программу для разбиения полигонов на треугольники (треугольники раскрасить разным цветом).
6. Написать программу для вычерчивания проволочной модели куба в трехмерном пространстве. Начало мировых координат выбирается в центре куба.
7. Вычертить сложную фигуру (куб, цилиндр, пирамида и т.п ).
8. Написать программу для моделирования освещения объектов по Фонгу (двух сфер).
9. Написать программу для отображения сложного объекта в динамике (вращение, приближение, удаление, освещенность).


Внимание, запрос: подскажите, пожалуйста, адекватные учебные пособия по С#(впрочем, все равно каком, лишь бы сделать, в C# проще ИМХО). Хотелось бы примерно такого стиля как здесь:http://stavkombez.ru/method/INFORMATICS/praktiki/6.htm или здесь http://hi-intel.ru/802/1.html. Книги, талмуды не хочу: нет столько времени и сил, чтобы пережевывать сотни страниц текста, когда мне по сути и надо-то всего ничего. Видеолекции/видеокурсы котируются, но хорошие. Опыт в программировании есть, неплохо справлялся в Delphi. Буду очень признателен.
Автор: juvaforza
Дата сообщения: 21.10.2012 22:21
RoMiGoR
А endl тоже убирали?

Kars25rus
Вы, наверное, здесь хотели спросить.
Автор: RoMiGoR
Дата сообщения: 21.10.2012 23:23
juvaforza
Да, с endl программа работает ~3 секунд, с '\n' ~2.5 секунд. В данном случае странно то, что cin работает быстрее scanf'a, а cout работает медленнеe printf'a.
Автор: YuriyRR
Дата сообщения: 22.10.2012 01:14
Kars25rus
Написать программу, генерирующую полигон произвольной формы с n-вершинами (n=100).
Это точно есть в бесплатной библиотеке Allegro.
Автор: juvaforza
Дата сообщения: 22.10.2012 12:58
RoMiGoR
Это вы их вместе проверяли или в отдельности (напр., отключая вывод, заменяя ввод на переменную цикла)?
Автор: Kars25rus
Дата сообщения: 22.10.2012 13:12
YuriyRR
Знаете, препод сказал как отрезал: "Всё писать самим. Сторонние средства не использовать". Так что, спасибо, конечно, за совет, но мне это не подходит

juvaforza
Я последую вашему совету, и перенесу свой вопрос в секцию "Программирование в среде .NET (ASP.NET,ADO.NET) на C#/VB.NET".
Автор: RoMiGoR
Дата сообщения: 22.10.2012 14:57
juvaforza
Всё по отдельности, сначала поменяли на '\n', потом пробовали все комбинации из потоков и стандартных вводов, cin + printf работает быстрее всех.
Автор: ne_viens
Дата сообщения: 22.10.2012 15:47
Быстрее даже чем:
ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, sizeof(buf), &tmp, 0);    
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, tmp, &tmp, 0);
?!
Автор: juvaforza
Дата сообщения: 22.10.2012 16:44
RoMiGoR
Я имел в виду как-то так по отдельности:
Цитата:
// cin >> n;
n = 50000;
for (long long i = 2013; i < (n + 2013); i++)
{
// cin >> year;
year = i;
cout << Year[year % 400] << '\n';
}

Цитата:
cin >> n;
/*for (long long i = 0; i < n; i++)
{
cin >> year;
cout << Year[year % 400] << endl;
}*/
Автор: RoMiGoR
Дата сообщения: 22.10.2012 17:15
juvaforza
Так как задачу надо было загнать с вводом, то я его не отключал.
ne_viens
Там файлового ввода/вывода не было.
Автор: juvaforza
Дата сообщения: 23.10.2012 13:40
RoMiGoR
Я к тому, что такая разница может быть из-за std::cin.tie(&std::cout). Попробуйте с cin.tie(0).

P. S.
Для потока вывода при использовании отдельного буфера результаты одинаковые (для cout и printf, с той частью кода) и быстрее стандартной реализации.
Цитата:
setvbuf(stdout, buf, _IOFBF, buf_sz);
std::cout.rdbuf()->pubsetbuf(buf, buf_sz);


Если отключить буферизацию stdout, то результат приблизительно совпадает с результатом cout и буфером компилятора (gcc-tdm, VS10).
Цитата:
setvbuf(stdout, buf, _IONBF, buf_sz);


gcc-tdm при использовании sync_with_stdio(false) сам увеличивает буфер cout, в остальном результаты с VS совпадают.
Автор: RoMiGoR
Дата сообщения: 23.10.2012 20:05
juvaforza
А можете подсказать хорошую статью по вводу/выводу в C++? Просто все вещи, которые вы пишите, я вижу впервые.
Автор: juvaforza
Дата сообщения: 23.10.2012 23:51
RoMiGoR
Я тоже ничего знал (и не думаю, что знаю) про буферизацию потоков и гуглил 1, 2, 3, 4, 5 (или 5), 6, 7, 8, также странички с stackoverflow, cplusplus и msdn.

Самое хорошое, имхо, - 1, 4-6. Метод tie() - это просто еще одно условие очищения буфера cout, две другие функции - стандартные функции для создания своего буфера. Без их использования - буфер определяется компилятором. Но какие параметры каждого компилятора влияют и какие ограничения имеет использование своего буфера - я не скажу.

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193

Предыдущая тема: не знаю как назвать тему :-)


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.