В общем вопрос в заголовке, что за перегружаемый(если уместно применить к этому слово
перегружаемый) оператор "" и зачем он используется?
long double operator "" _w(long double);
std::stringoperator "" _w (const char16_t* , std::size_t) ;
unsigned operator "" _w(const char*);
int main {
1.2_w; // вызов operator " " _w (1.2L)
u"one"_w; // вызов operator "" _w (u"one", 3)
12_w; // вызов operator " " _w ("12")
"two"_w; // ошибка: нет применимой литеральной операции
}
Ответы
Ответ 1
Приведу пример, для чего это может быть использовано:
constexpr unsigned long long operator"" _kb ( unsigned long long _bytes)
{
return _bytes * 1024;
}
constexpr unsigned long long operator"" _mb ( unsigned long long _bytes)
{
return _bytes * 1024_kb;
}
Данные операторы позволяют затем в коде использовать конструкции вида:
int64_t buffer = 50_mb;
Что по факту будет преобразовано в
int64_t buffer = 52428800;
Но, на мой взгляд, запись 50_mb сама за себя говорит что это за число.
Так же такой механизм удобно использовать для обозначения времени:
constexpr unsigned long long operator"" _sec ( unsigned long long _sec)
{
return _sec * 1000;
}
constexpr unsigned long long operator"" _min ( unsigned long long _min)
{
return _min * 60_sec;
}
И далее использовать как:
int delay = 15_min;
Ответ 2
Это пользовательские литералы.
Подробнее можно почитать по запросу в гугле, или, например, на хабре .
Также стоит почитать здесь .
Ответ 3
#include
#include
int main()
{
using namespace std::chrono_literals;
//3s - пользовательский литерал, определённый в std::chrono_literals
std::chrono::milliseconds interval = 3s;
/// выведет 3000 - 3000 миллисекунд
std::cout << interval.count() << std::endl;
///А ещё есть префиксный строковый литерал, вопринимающий символы как есть
///Выведет \n\n
std::cout << R"(\n\n)" << std::endl;
return 0;
}
Пользовательские литералы, которые Вы сами определяете, необходимо отделять символом
подчёркивания, чтобы они не конфликтовали с литералами, входящими в стандартную библиотеку
- как 3s из std::chrono_literals в примере
Предлагаю использовать этот вопрос как некий конкурс, далее выделю 500рп тому,
чей ответ наберёт большее кол-во голосов "за".
Условие
Есть код, который позволяет передвигать блок определённых границах (в данном случае
это квадрат).
let reg = $('.region'), obj = $('.region .object');
reg.on('mousemove', function(e){
let p = {
// region size
rW: reg.width(), rH: reg.height(),
// object size
oW: obj.width(), oH: obj.height(),
// mouse position
mY: e.pageY - reg.offset().top, mX: e.pageX - reg.offset().left,
// object position (center)
oY: obj.width() / 2, oX: obj.height() / 2
};
// object moving
obj.css({
'top': p.mY <= p.oY ? 0 : p.mY >= p.rW - p.oW ? p.rW - p.oW : p.mY - p.oY,
'left': p.mX <= p.oX ? 0 : p.mX >= p.rH - p.oH ? p.rH - p.oH : p.mX - p.oX
});
});
body {
width: 100wh; height: 100vh;
margin: 0;
overflow: hidden;
position: relative;
}
.region {
display: block;
width: 200px; height: 200px;
box-shadow: 0 0 0 2px blue;
position: absolute;
left: 0; top: 0; right: 0; bottom: 0;
margin: auto;
}
.object {
display: block;
width: 20px; height: 20px;
background: red;
position: absolute;
left: 0; top: 0;
pointer-events: none;
}
Тут даже ежу понятно, что "механика" слишком простая, ибо форма примитивная.
А как быть, к примеру, если форма, по которой нужно будет ограничить движение - будет
являться фигурой, допустим кругом, треугольником или каким-то сложной (относительно)
фигурой.
Задача
Сделать движение элемента по ограниченной фигуре (одной или несколько), в приоритете
круг, треугольник.
Нюансы
Как можно меньше трогать вёрстку html.
желательно использовать "динамические" размеры фигуры (т.е. получать от самой фигуры
(если это представляет возможности).
Итоги
Конкурс продлиться до 12.08.19
Ответы
Ответ 1
Предлагаю вот такой вариант.
В лоб за O^2n обходим аппроксимации обоих путей и ищем точки пересечения....
let borderPts = getPoints(border),
figurePts = getPoints(figure),
drag;
addEventListener('mouseup', e => {
drag && (drag.element.style.pointerEvents = 'all');
drag = null;
});
addEventListener('mousedown', e => {
let tr = e.target.getAttribute('transform');
if (!tr) return;
let xy = tr.split(/\(|\)|\,/);
drag = {x: xy[1] - e.x, y: xy[2] - e.y, element: e.target};
e.target.style.pointerEvents = 'none'
});
let debugPoint = pt => ``;
addEventListener('mousemove', e => {
if (!drag) return;
let intersectionPts = intersect(e.x, e.y);
let canMove = e.target === border && intersectionPts.length === 0;
drag.element.setAttribute('stroke', canMove ? 'black' : 'red' );
if (mode.checked)
debug.innerHTML = intersectionPts.map(debugPoint).join('');
if (canMove || mode.checked)
drag.element.setAttribute('transform',
`translate(${drag.x + e.x},${drag.y + e.y})`);
});
function intersect(x,y) {
let pts = figurePts.map(pt => [pt[0] + x + drag.x, pt[1] + y + drag.y]);
let points = [];
forEachPair(pts, (pt1, pt2) => {
forEachPair(borderPts, (pt3, pt4) => {
let intersection = findIntersection(...pt1,...pt2,...pt3,...pt4);
intersection && points.push(intersection);
});
});
return points;
}
function forEachPair(pts, f) {
for (let i = 0; i {
let p = path.getPointAtLength(t*precision);
return [p.x, p.y];
});
}
function findIntersection(x1, y1, x2, y2, x3, y3, x4, y4) {
// http://paulbourke.net/geometry/pointlineplane/
let denom = (y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1);
if (denom == 0)
return null;
let ua = ((x4 - x3)*(y1 - y3) - (y4 - y3)*(x1 - x3))/denom;
let ub = ((x2 - x1)*(y1 - y3) - (y2 - y1)*(x1 - x3))/denom;
if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
return {
x: x1 + ua * (x2 - x1),
y: y1 + ua * (y2 - y1)
};
}
mode
Ответ 2
Для двух окружностей все еще проще чем для прямоугольника, необходимо лишь посчитать
что расстояние между центрами не больше чем разница радиусов большой и малой окружности.
В этом случае не сложно сделать так, чтобы при коллизии малая окружность не упиралась
и могла перемещаться в направлении курсора не выходя за границы большой.
Для этого вычисляем вектор направления от центра большой окружности до курсора и
умножаем его на разницу радиусов.
let x = +bounds.getAttribute('cx');
let y = +bounds.getAttribute('cy');
let dr = +bounds.getAttribute('r') - drag.getAttribute('r');
addEventListener('mousemove', e => {
let dy = y - e.y;
let dx = x - e.x;
if (dx*dx + dy*dy < dr*dr) {
dx = e.layerX;
dy = e.layerY;
} else {
let a = Math.atan2(dy, dx);
dx = x - Math.cos(a)*dr;
dy = y - Math.sin(a)*dr;
}
drag.setAttribute('transform', `translate(${dx},${dy})`);
});
Берем простой код:
void main() {
int x = abs(-1);
}
Собираем и дизассемблируем его:
$ gcc sample.c -o sample && objdump -d ./sample
Получаем листинг, где нет условной команды:
80483a1: e8 ee ff ff ff call 8048394
80483a6: 89 c2 mov %eax,%edx
80483a8: c1 fa 1f sar $0x1f,%edx
80483ab: 31 d0 xor %edx,%eax
80483ad: 29 d0 sub %edx,%eax
Как на C/C++ получить абсолютное значение целого числа без операции сравнения?
Ответы
Ответ 1
ассемблерная операция sar это обычный сдвиг вправо.
Вот ваш код:
int myabs(int x)
{
//mov %eax,%edx
//sar $0x1f,%edx
int minus_flag = x>>0x1F;//0x1F = 31
//xor %edx,%eax
int y = minus_flag ^ x;
//sub %edx,%eax
y -=minus_flag;
return y;
}
Ответ 2
Я лучше ориентируюсь в Java, поэтому чтобы не выглядить глупо код не буду писать на C :)
Но с алгоритмической точки зрения это должно выглядеть примерно так:
(Я полагаю, на С/С++ представление знакового целого сделано с помощью дополнительного
кода)
Скопировать куда-нибудь первый бит.
Создать новую целую переменную такого же размера.
Скопировать во все биты второго числа значение сохранённого ранее бита.
Применить побитовое "исключающее или" первого числа ко второму (XOR).
Прибавить к получившемуся числу значение сохранённого ранее бита.
Приведу таблицу действий для чисел -5 и 3 которые хранятся в 8 битах.
число1 доп.число1 доп.бит1 число2 доп.число2 доп.бит2
11111011 00000000 1 00000011 00000000 0
11111011 00000000 1 00000011 00000000 0
11111011 11111111 1 00000011 00000000 0
00000100 11111111 1 00000011 00000000 0
00000101 11111111 1 00000011 00000000 0
Алгоритм не супер, но он без сравнений :)
Ответ 3
Первое, что пришло на ум, сразу после прочтения вопроса, - это взять квадратный корень
из квадрата числа:
sqrt(x*x)
Другой вариант - это, как уже здесь отмечалось, воспользоваться знаниями о представлении
числа и дополнительном коде и побитовыми операциями.
Пример для 8-битных чисел
char x = -5;
char minus = (x & 0x80) >> 7; // равно 1 если x - отрицательное и 0 если
положительное
char plus = (((x & 0x80) >> 7) + 1) & 1; // наоборот, равно 1, если x - положительное,
и 0 если отрицательное
char abs_x = minus * (-x) + plus * x;
Для int будет сложнее, т.к. нужно будет учитывать кучу особенностей, например, разрядность
(int может быть 8, 16, 32, 64-разрядной) и порядок байтов (Little-Endian/Big-Endian).
Ответ 4
Алгоритмический трюк, на котором основано вычисление модуля без ветвлений, заключается
в свойстве дополнительного кода. Операция xor с числом -1 даёт инвертирование битов
числа, а прибавление 1 завершает переход к отрицанию числа. Причем само число -1 получается
как знаковый сдвиг вправо исходного числа, если оно было отрицательным. Если же число
было положительным, что сдвиг даст 0, поэтому xor и sub ничего не изменят. Подробнее
о подобных алгоритмах вычисления модуля и о скорости их работы можно прочитать здесь.
Я сейчас изучаю C# по учебнику Шилдта, а он учит заключать все узкие моменты в try-catch.
Это нормальная практика ветвления кода, или лучше пользоваться if-else? Я, конечно,
понимаю разницу между ошибками и исключениями. Но теперь у меня расплывается граница
между некоторыми исключениями и обычными ветвлениями в коде.
Например операция деления одного числа на другое подразумевает, что пользователь
может (попробовать) поделить число на ноль. С одной стороны результат этой операции
будет исключением, которое можно обработать. С другой стороны можно и не доводить дело
до исключения, заранее проверяя вводимые числа.
Как принято поступать в обществе профессиональных программистов?
Ответы
Ответ 1
Вообще подмена исключений условными блоками - не самая здравая идея. Любая функция
(метод) в принципе должна выполнять одну возложенную на нее задачу. Если по тем или
иным причинам задача выполнена быть не может, то должно быть брошено исключение. Сам
метод в общем случае не должен заниматься обработкой собственных исключений, для этого
есть вызывающий его код. Метод должен либо выполнить задачу, либо сообщить о невозможности
ее выполнения. Вернемся к вашему примеру:
Например операция деления одного числа
на другое подразумевает, что
пользователь может (попробовать)
поделить число на ноль. С одной
стороны результат этой операции будет
исключением, которое можно обработать.
С другой стороны можно и не доводить
дело до исключения, заранее проверяя
вводимые числа.
В этом случае должно быть именно вызвано исключение - ваш метод получил некорректные
входные данные, и не может правильно произвести операцию деления. Тут интересна такая
ваша фраза:
С другой стороны можно и не доводить
дело до исключения, заранее проверяя
вводимые числа.
Можно. Но что должен делать код дальше, если проверка не прошла? Вернуть некое магическое
значение типа -1 или 0? Это будет некорректно с точки зрения логики. Вывести сообщение
об ошибке? Это будет попахивать ошибкой проектирования - отвечать за вывод сообщений
об ошибках должен совсем другой код. Появится связность кода, а это очень плохо.
Помимо того, существуют такие исключительные ситуации, в которых никакие if-else
не помогут. Скажем, не удалось открыть соединение базой данных. Что программа должна
делать дальше? Войти в условие и попытаться еще раз открыть его, а затем еще, еще и
еще? Вряд ли.
Ну а что касается if-else, то их имеет смысл использовать там, где "не сработавший"
вариант - всего лишь одно из возможных корректных состояний программы.
Резюмирую - метод должен либо выполнить задачу, либо сообщить о невозмождности ее
выполнения. Обрабатывать собственные исключения чаще всего не нужно. Следует пробрасывать
их вверх.
Весьма рекомендую также прочесть у Рихтера главу, посвященную исключениям. Да и вообще
саму эту книгу
Ответ 2
Нет, я не согласен с Шилдтом.
Обычно код структурируется таким образом, что:
Большинство операций имеют право выбросить исключение. Они не ловят исключения вызываемого
кода, кроме редких случаев, где это действительно нужно.
Если у вас происходит ручное управление ресурсами, вам скорее всего пригодится try/finally,
а не try/catch
try/catch оборачивает как можно большие, внешние блоки программной логики. Например,
итерацию главного цикла.
По поводу того, где использовать исключения, а где if/else: если операция может ожидаемо
завершиться неудачей, используйте ветвление. Если операция завершается неудачно лишь
в исключительных случаях, используйте исключения.
Пример: если пользователь ввёл текст в editbox, вы не можете исходить из того, что
он ввёл число. Используйте такой код:
if (int.TryParse(s, out value))
return value;
else // покажите message box и не закрывайте диалог
В случае, если значение читается из конфигурационного файла, нечисловое значение
там, где ожидается число — серьёзная проблема, и код соответственно меняется:
return int.Parse(s); // если там не число, бросаем исключение, которое
// будет поймано на верхнем уровне операцией чтения конфигурации
Дополнительное чтение по теме: http://www.artima.com/intv/handcuffs.html
Ответ 3
Ветвление - это нормальное поведение программы. Исключения указывают на потенциальную
деформацию логической целостности некой модели, от чего ее нужно спасать (закрывать
соединения, прекращать работу с объектом и т.п.).
Вот в C++ как вы и сказали, исключения добавлены как вспомогательный не обязательный
механизм. Но try-catch зачастую читается куда лучше, чем хитроумный контроль за валидностью
объекта по многим критериям, специальным переменным.
У меня есть представление как работает этот класс, но хочется понять в какой ситуации
его реализация принесет мне выгоды, я не могу даже придумать, помогите пожалуйста разобраться.
Ответы
Ответ 1
BlockingQueue - это очередь Queue со следующими дополнениями:
Блокирующая операция take() - берет следующий элемент, если же очередь пустая - блокирует
выполнение до появления элемента (до момента, когда перестанет быть пустой)
Блокирующая операция put(E e) - помещает элемент в очередь, если очередь заполнена
- блокирует выполнение до освобождения места в очереди и успешного помещения в нее
нового элемента.
Предназначена для реализации взаимодействия "поставщик - потребитель". Реализации
методов потокобезопасны (синхронизированы), так что и писать в нее, и читать из неё
можно в несколько потоков. Цитата из JavaDoc:
Note that a BlockingQueue can safely be used with multiple producers
and multiple consumers.
Пример 1:
Пусть есть магазин с 3 входами и 2 кассами. Покупатели прут через 3 входа и выходят
через 2 кассы. Очередь в кассы общая. Целесообразно хранить очередь покупателей в BlockingQueue.
Пример 2:
Имеется конвейер, выпускающий детали. Для производства нужны заготовки. С нескольких
автоматов предыдущего этапа производства поступают заготовки, роботы берут их и делают
из них детали. На следующем этапе эти детали используются для производства узлов другими
роботами. Целесообразно хранить очередь входящих заготовок и очередь исходящих деталей
(для следующего этапа) в BlockingQueue.
Ответ 2
BlockingQueue - как можно понять из документации используется для того, чтобы выполнить
операцию над данными в другом месте или времени, не там где они были получены.
Самый распространенный пример это обработки сообщений(обновление данных). Получаются
данные(эвенты) в одном потоке(их может быть несколько) и записываются в BlockingQueue,
в это же время другой потом(он должен быть один) ожидает элементов в этой очереди(метод
take) и как только получает данные начинает обработку. Это позволяет избежать ситуации,
когда несколько потоков пытаются записать одни и те же данные.
Класс ведь ссылочный тип, а переменные в классе могут быть типами по значению. Например:
class Car
{
public int maxSpeed;
public Car(int max)
{
maxSpeed = max;
}
}
Где хранится maxSpeed — в стеке или куче?
Ответы
Ответ 1
Сам по себе вопрос вызван двумя проблемами
достаточно распространенным, но в общем случае неверным утверждением "переменные
value-type хранятся в стеке"
небольшой путаницей в терминологии - поля класса это не "переменные" - не локальные
переменные.
Дело в том, что на уровне языка C# нет понятия "стэк" и "куча". Есть два вида типов:
Ссылочные. Значение переменной или поля класса этого типа хранит в себе адрес памяти,
по которому лежит экземпляр типа. Сам по себе экземпляр при этом обычно лежит в куче.
Пример - строки.
Value-types (типы-значения). Значение переменной или поля класса хранит значение
напрямую. Пример - int.
Понятие стека есть на уровне .NET/IL. Локальные переменные в методах уровня IL .NET
хранятся в стеке. Переменная C# превращается в переменную метода IL далеко не всегда.
Это происходит, если:
на нее нет замыканий
она объявлена в не-async-методе
еще много разных условий, вызванных особенностями реализации конкретного компилятора C#.
Поля типов хранятся как часть самого экземпляра типа. Они физически лежат в том куске
памяти, который выделен под конкретных экземпляр типа. Т.е. если экземпляр сам по себе
лежит в стеке (например, это экземпляр структуры) - то поле хранится в стеке. Если
экземпляр лежит в куче - то и поле лежит в куче.
Конкретные примеры
В методе объявлен int a - он лежит прямо в стеке
В методе объявлен string s - в переменной в стеке лежит адрес строки в куче.
В методе объявлен Car c - в переменной в стеке лежит адрес объекта Car. Сам объект
лежит в куче. Частью объекта в куче является поле maxSpeed, в нем лежит значение скорости.
В методе объявлен int [] arr - в переменной в стеке лежит адрес массива в куче. Прямо
в объекте массива в куче лежат значения отдельных ячеек.
Объявлена структура Point с полями X/Y. В методе объявлена переменная Point p - в
переменной в стеке лежит сама структура, со всеми полями.
Ответ 2
Перевод ответа на аналогичного вопрос на английском
Типы-значения называются "типы-значения", потому что копируются по значению. Ссылочные
типы называются "ссылочными типами", потому что копируются по ссылке. Это не совсем
верно, что "типы-значения всегда находятся на стеке". Если бы это было правдой они
бы назывались "Типы стека"(stack types) и "Типы кучи"(heap types).
Правда в том, что все зависит от деталей реализации. Различные реализации фреймворков
могут выбирать использовать им стек или кучу, так как они хотят. Ниже пример как это
реализовано у Микрософта:
значение переменной ссылочного типа указывает на значение в куче. Ссылки в основном
32-х или 64-х битное целое.
значение переменной значимого типа - это само значение.
значения локальных переменных хранятся на стеке, пока эти переменные не в блоке итератора,
или не замкнуты в анонимном методе или лямбда-выражении. В этих случаях значения локальных
переменных хранятся в куче. Конечно, пока эти переменные не выкинуты оптимизатором,
в этом случае они нигде не хранятся. Или, возможно они могут быть перенесены в регистры
и в этом случае они не будут ни на стеке, ни в куче.
значения экземпляров ссылочных типов и статические переменные хранятся в куче.
maxSpeed - это поле, следовательно, хранится в куче.
Единственная вещь идущая в стек - это локальные переменные (и временные переменные
сгенерированные компилятором), которые не замкнуты в лямбда функциях или анонимных
методах, и не находятся в блоке итератора. И, конечно, jitter может не использовать
стек, а сложить все в регистры, если достаточно свободных регистров.
Но, на самом деле, я должен спросить: почему вы беспокоитесь о том, что пойдет в
стек, а что в кучу? В стек идет только то, что мы можем быстро положить в него, все
остальное идет в кучу.
Ответ 3
Объекты класса хранятся в куче. А что представляет собой экземпляр класса? По-сути,
тип да набор своих переменных.
А в стеке хранятся те переменные, которые объявляются внутри функций/методов. Отсюда
и проблема переполнения стека при чрезмерном рекурсивном вызове функций (см. название
сайта :)).
Возможно ли в С вывести что-нибудь в консоль, не используя stdio.h, printf?
Ответы
Ответ 1
stdio.h - это буферизированная надстройка над базовыми функциями ввода-вывода read,
write, объявленными в unistd.h.
#include
write(1, "Hallo!\n", sizeof "Hallo!\n" - 1);
Первый аргумент - файловый дескриптор - номер в таблице открытых файлов исполняемой
программы. При запуске по стандарту заранее открыты три дескриптора: 0 - стандартный
ввод, 1 - стандартный вывод, 2 - стандартный вывод ошибок. В некоторых системах могут
быть ещё другие.
fwrite из того же stdio.h. Работает похожим образом, но через тот же буфер, как и
printf:
#include
fwrite("Hallo!\n", sizeof "Hallo!\n" - 1, 1, stdout);
Хотя она и вызывает write, но за счёт буферизации часто оказывается быстрее при записи
большого количества данных в файл (при перенаправлении вывода). Безусловно fwrite быстрее
printf, так как последняя ищет в строке форматные последовательности, начинающиеся
со знака %.
fputs и puts из stdio.h выводят строку, оканчивающуюся нулевым байтом ('\0'). Вторая
добавляет ещё и символ конца строки и выводит только на стандартный вывод.
#include
fputs("Hallo!\n", stdout);
puts("Hallo!"); // выводит то же самое, что и предыдущая функция
По скорости должны быть как fwrite, но отличаются способом определения длины строки,
поэтому с их помощью невозможно вывести сами нулевые байты. Мои измерения в ubuntu
однако показывают, что puts почему-то намного медленнее fputs и почти как printf.
Ответ 2
В дополнение к POSIX write(2) и Win32 WriteConsoleW() можно упомянуть функции,
которые также позволяют выводить в консоль:
Библиотечные функции, объявленные в conio.h, весьма различались в
зависимости от компилятора. Первоначально реализованные в Microsoft
Visual C++ различные функции привязывались напрямую к нескольким
первым функциям DOS, связанным с прерыванием 21h. Но библиотека,
поставляемая с Turbo C++ и Borland C++, не использует DOS API, а
вместо этого напрямую обращается к видеопамяти для вывода информации и
использования сигналов прерывания BIOS.
#include
putch('A');
Также (зависит от железа, ОСи) можно выводить символы на экран с помощью прямой манипуляции
памяти, которая отображена на видео буфер. Из книги "Computer Graphics Primer", написанной
Mitchell Waite и опубликованной в 1979:
IBM VGA BIOS (mode 13h) режим предоставляет похожий доступ к видеопамяти как к 320×200
массиву пикселов с 256 цветами.
Обычно между программой и видеопамятью присутствует множество уровней абстракции.
На Linux, если X не запущен(или в Ctrl+Alt+Fx виртуальной консоли), можно mmap /dev/fb0
устройство (Linux framebuffer всего на ступеньку выше работы с видеокартой напрямую—интерфейс
предоставляется самим ядром):
fbdev = open("/dev/fb0", O_RDWR);
buffer = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbdev, 0);
Здесь buffer—это массив байтов размером screensize, запись в который позволяет рисовать
в консоли, например, в режиме 1600x1200 32bpp (screensize = 1600*1200*32/CHAR_BIT),
чтобы закрасить выбранный пиксель ярко жёлтым (красный+зелёный):
buffer[i+0] = 0; // синий
buffer[i+1] = 255; // зелёный
buffer[i+2] = 255; // красный
buffer[i+3] = 0; // прозрачность
Вот пример кода, как квадрат нарисовать в консоли, используя framebuffer: How to
display something on screen through linux framebuffer?
Ответ 3
Для винды: WriteConsole().
Для DOS - формирование кода вызова INT 21 и через передачу управления на него.
Ответ 4
#include
/* для любой linux системы. У меня gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 */
int main()
{
int i = system ("ls -al"); // показать файлы текущей директории в тч скрытые
return 0;
}
Ответ 5
Borland C++ 3.1:
#include
int main()
{
putch('7');
return 0;
}