C++ — Помогите решить вопрос в C++ пожалуйста!


Содержание

C++ — Помогите решить вопрос в C++ пожалуйста!

Только если скомпилировать файл типа .c , но не .cpp , например, делать так было можно в «чистом» C:

Можно ли в C++ одновременно использовать одноимённые локальную и глобальную переменные?

Да. Оператор области видимости ::

Можно ли в C++ вызвать функцию слева от знака «=»?

Да, например, так:

Можно ли в C++ получить доступ к приватным свойствам класса без использования методов-членов или функций-друзей класса?

Ага :) Указатели-то на что?

Можно ли в C++ сделать класс, объекты которого можно будет создавать только динамически?

Угу. Сделав деструктор приватным, мы лишим компилятор возможности удалять созданные в стеке объекты, на что он будет ругаться ошибкой компиляции.

А для удаления динамических объектов кучи можно предусмотреть отдельную функцию-друг класса. Это будет платой за «защиту от стека».

Можно ли в C++ сделать класс, объекты которого наоборот можно будет создавать только в стеке, но не динамически в куче?

Да. В противоположность предыдущему пункту, можно определить в классе приватный оператор new .

Можно ли в C++ из пустой функции main что-нибудь вывести в консоль?

Да. Скажем, создав глобальный объект класса, который выводит что-то в консоль из конструктора.

Также класс можно заменить структурой или просто глобальной переменной:

Можно ли в C++ напечатать натуральный ряд чисел, не используя цикла или рекурсии?

Да. Можно использовать шаблоны класса и статические функции.

. или просто массив объектов класса и статическую переменную.

Можно ли в C++ найти сумму всех цифр числа одним оператором?

Да, если это оператор цикла for

Можно ли в C++ писать URL-адреса прямо в тексте программы?

Да. Полную ссылку, которая начинается с названия протокола, можно вставить в текст программы без каких-либо символов-ограничителей.

Просто http: воспринимается как метка, а всё, что за символами // — как комментарий :)

Можно ли в C++ поменять местами значения 2 переменных без использования третьей переменной или арифметических операций?

Да. Есть ещё побитовые операции и операция следования (запятая).

Можно ли в C++ из пользовательской программы завершить работу системы?

Да, поскольку доступна функция system . Наверное, не буду выполнять этот код :)

На самом деле, современные ОС попросят подтвердить действие.

Можно ли в C++ сравнить значения 2 переменных без использования оператора сравнения (==)?

Да. Побитовое исключающее «или».

Можно ли в C++ напечатать ряд натуральных чисел 1,2. N, не используя ни одной точки с запятой?

Рекурсивный вызов функции main позволяет решить эту задачу, например, так:

Можно ли в C++ найти максимум или минимум из двух целочисленных значений, не используя условий или циклов?
Можно ли в C++ сложить 2 числа, не используя операцию сложения?

Да. Есть же вычитание :)

Можно ли в C++ выполнить обе ветви условного оператора «если-то-иначе»?
Можно ли в C++ умножать или делить целое значение на степени двойки, не используя операций «*» или «/»?

Это можно делать в любом языке, где есть побитовый сдвиг. Умножению значения x на 2 , например, соответствует операция x , а делению y на 4 — действие y >> 4 . Не путайте операторы побитового арифметического сдвига с переопределёнными в некоторых классах (например, в классах поточного ввода-вывода) операторами вставки >.

Можно ли в C++ проверить порядок байтов (big-endian/little-endian) компьютера?

Для многобайтовых величин имеет значение, в каком порядке хранятся байты числа.

Порядок байтов бывает big-endian (от старшего к младшему) и little-endian (от младшего к старшему).

Например, десятичное число 10000 равно 0x2710 в 16-ричном виде и «естественном» представлении big-endian, а в little-endian это будет 0x1027. Именно так может храниться значение на линейке процессоров x86 :)

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

Можно так, если не хочется искать константу, содержащую это значение:

Можно ли в C++ найти знак числа без использования любого (бинарного или тернарного) условного оператора?

Так как результаты выполнения операций отношения можно рассматривать как числовые значения, то вот так:

Можно ли в C++ заполнить двумерную матрицу размерности n x m последовательно идущими числами 1,2,3. применяя только один цикл?

Остаток от деления и целочисленное деление C++ (целое поделить на целое дают целое) рулят.

У класса есть конструктор с одним целочисленным аргументом. Покажите три синтаксически различных способа создать экземпляр класса с помощью этого конструктора

Поможет «редкий» способ 3 для конструктора с одним аргументом.

Как запретить автоматическое преобразование типов в конкструкторе (не создавать объекты способом 3 из предыдущего вопроса)?

Для того и нужно ключевое слово explicit

Всегда ли при выполнении операции вида a = b, где a и b — объекты одного класса, вызывается конструктор копирования?

Неа, не всегда. Конструктор копирования применяется только к инициализациям, но не к присваиваниям.

Как определить для объектов класса сложение с числом в виде Obj+i и i+Obj?

Для решения задачи можно использовать, например, пару функций-«друзей» класса.

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

Даже не знаю, почему этот вопрос здесь. обычное, в общем, приведение типов :)

Как классу «выдать себя» за своего предка, то есть, использовать его виртуальный метод?

Так как атрибут virtual передается по наследству через все уровни наследования, можно просто не переопределять на нужном уровне наследования метод, объявленный в предке виртуальным ( show )

Как «заставить» класс-потомок определить виртуальный метод?

Определить в предке чисто виртуальную функцию ( show ). Иначе это называется «сделать класс абстрактным»

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

Вариант 1. Написать для этого типа альтернативный шаблон функции

Вариант 2. Написать для этого типа явно заданную функцию

Как инициализировать члены класса в конструкторе, не обращаясь к ним из тела функции-конструктора?

Список инициализации в конструкторе.

06.03.2020, 17:06; рейтинг: 1377

Русские символы(буквы) при вводе/выводе в консоль на C++

При изучении языка C++ и программировании под Windows довольно часто возникают вопросы по поводу отображения русских букв в консоли. Вывод и ввод русских букв сопровождается выводом и вводом каких-то кракозябр или иероглифов. В интернете можно найти довольно много советов, но большая часть советов, которые мне попались, не помогали в решении проблемы.

Возникла проблема с отображением русских букв

Если нужно быстрое решение данной проблемы, то можно сразу пролистать вниз, ибо сначала я расскажу о том, как возникла эта проблема у меня и о том, как я искал решение.

На языке C++ программирую под ОС Linux, использую компилятор GCC. С проблемой неправильного отображения русских букв я не сталкивался. В момент написания статьи я нахожусь далеко от своего компьютера, могу довольствоваться лишь скромненьким ноутбуком с установленной ОС Windows Seven. Захотелось покодить и я установил на него интегрированную среду разработки Dev-C++ 5.10(использует компилятор TDM-GCC 4.8.1 на базе GCC 4.8.1). Кстати, она уже официально не поддерживается, но существует форк Orwell Dev-C++, который обновляется по сей день. Установив, я запустил и для пробы написал простую программку, которая отображает текст «Привет, мир!». Но поздороваться она с миром так и не смогла, а лишь сказала что-то непонятное на древнеегипетском. После перелопачивания некоторых форумов и сайтов я нашел множество советов, но основная масса не способна была решить её полностью, образовывались подводные камни о которых расскажу далее.

Цукерберг рекомендует:  Обучение - При создании бота, ругается на функцию

После написания, компиляции и запуска такой программы:

Developing.ru

Задачка на C++, ПОМОГИТЕ ПОЖАЛУЙСТА НЕДОПРОГРАММИСТУ

Задание есть, код тоже есть. Вот только вопроса нету. Что именно не так или что хочется сделать?

Одним глазом посмотрел код. В конструкторе, который принимает укатель на char, не проставляется терминирующий ноль. Во втором конструкторе, терминирующий ноль проставляется в неправильно место (должен проставляться в n-й символ).

Мария, вы меня зарезали без ножа. Вы взяли программу однокурсника, который слушает Linkin Park, написали в тестрируемой строке «I!love. Programmirovanie!», также изменили табуляцию в одном из методов, и теперь хотите сдать эту программу, выдав за свою? На самом деле я ожидал, что вы исправите ошибку, на которую я указал ранее, а не убьёте остатки моей мотивации транслитерированным словом «Programmirovanie». Вы меня извините, но я в этой теме больше ничего писать не буду.

И кстати, то, что у вас экзамен, не освобождает вас от необходимости учиться.

Romeo писал(а): Мария, вы меня зарезали без ножа. Вы взяли программу однокурсника, который слушает Linkin Park, написали в тестрируемой строке «I!love. Programmirovanie!», также изменили табуляцию в одном из методов, и теперь хотите сдать эту программу, выдав за свою? На самом деле я ожидал, что вы исправите ошибку, на которую я указал ранее, а не убьёте остатки моей мотивации транслитерированным словом «Programmirovanie». Вы меня извините, но я в этой теме больше ничего писать не буду.

И кстати, то, что у вас экзамен, не освобождает вас от необходимости учиться.

Извиняюсь за эмоции. Если вы готовы разбирать, то я окажу всяческую помощь. Просто я не знаю, откуда начать. Что такое класс, его конструктор и деструтор нужно объяснять? Или ещё раньше начать? Что такое переменная? Или наоборот всё понятно с классами, но не понятно, что такое терминирующий ноль?

Оценю конретные вопросы, на которые я с удовольствием отвечу.

Romeo писал(а): Извиняюсь за эмоции. Если вы готовы разбирать, то я окажу всяческую помощь. Просто я не знаю, откуда начать. Что такое класс, его конструктор и деструтор нужно объяснять? Или ещё раньше начать? Что такое переменная? Или наоборот всё понятно с классами, но не понятно, что такое терминирующий ноль?

Оценю конретные вопросы, на которые я с удовольствием отвечу.

Код C, который не будет работать в C++?

Вырезка из Википедии:

Синтаксис C++ унаследован от языка C. Одним из принципов разработки было сохранение совместимости с C. Тем не менее, C++ не является в строгом смысле надмножеством C; множество программ, которые могут одинаково успешно транслироваться как компиляторами C, так и компиляторами C++, довольно велико, но не включает все возможные программы на C.

И у Лафоре встречал такое заявление, что аки не каждый код на C будет скомпилирован компилятором C++. Спорить-то и нечего, но сколько помню, то все функции языка Си поддерживаются в C++. Обратная совместимость же!

Но можно ли узнать конкретно какой код не скомпилируется?

  • Вопрос задан более трёх лет назад
  • 1056 просмотров

посмотрите что-то из выделения памяти. malloc вроде работает и там и там, а другие варианты могут давать сбой.
Линковка в С++ немного отличается.

В общем можно писать совместимый код, а можно нарваться на какую-то мелочь, которая потребует архитектурной переделки.

Массивы переменной длинны (VLA).

Но всё зависит от компилятора и строгости следования стандарту. GNU компилятор, например, вводит такие массивы для C++ в расширениях.

Ещё в C есть restrict переменные, регистровые переменные, которых нет с C++.

C++ — Помогите решить вопрос в C++ пожалуйста!

Написать программу, которая создает одномерный массив из N целых чисел. Количество чисел в массиве и сами числа вводятся с клавиатуры. Вывести содержимое массива на экран.

Задача 2

Написать программу, которая выводит таблицу перевода расстояний в дюймах в сантиметры для значений от n до m дюймов (1 дюйм = 2,54 см)

Задача 3

Начав тренировки, спортсмен в первый день пробежал М км. Каждый день он увеличивал дневную норму на Р% нормы предыдущего дня. В какой день впервые спортсмен пробежит более K км?

Задача 4

Написать программу, которая создает одномерный массив из N целых чисел. Количество чисел в массиве и сами числа вводятся с клавиатуры. Вывести содержимое массива на экран. Вывести на экран среднее арифметическое элементов массива.

Задача 5

Написать программу, которая выводит таблицу умножения числа N в интервале от L до K. Ввод N, L,K выполнять с клавиатуры.

Задача 6

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

Задача 7

Написать программу, которая создает одномерный массив из N целых чисел. Количество чисел в массиве и сами числа вводятся с клавиатуры. Вывести содержимое массива на экран. найти и вывести на экран сумму всех четных элементов массива.

Задача 8

Клиент оформил вклад на m тысяч рублей в банке под k% годовых. Через сколько лет сумма вклада превысит s тысяч рублей, если за это время клиент не будет брать деньги со счета.

Задача 9

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

Задача 10

Написать программу, которая создает одномерный массив из N целых чисел. Количество чисел в массиве и сами числа вводятся с клавиатуры. Ввести число L. Все элементы массива больше L заменить на число 5. Вывести на экран элементы введенного массива и полученного.

Задача 11

Бизнесмен взял ссуду m тысяч рублей в банке под k% годовых. Рассчитать его долг через N лет , если за это время он не будет отдавать долг?

Задача 12

Написать программу, которая создает одномерный массив из N целых чисел. Количество чисел в массиве и сами числа вводятся с клавиатуры. Вывести содержимое массива на экран. Найти сумму элементов массива кратных 3.

Русский язык в консоли C++

Вы наверное не раз пытались вывести в консольное приложение русский текст, но вместо него выводились разные кракозябры.


К примеру, если мы напишем такой код на С++

То после компиляции, вот что будет выдавать нам консольное окно программы.

Если же мы будем использовать функцию setlocale() внутри функции main()

То получим вместо иероглифов нормальный русский шрифт, вуаля:

Также, можно опустить последний аргумент функции — setlocale(LC_ALL, «Russian»); можно заменить на setlocale(0, «»); — работоспособность программы от этого не изменится.

Могу ли я смешивать файлы c и cpp в одном проекте C ++?

Я все еще начинающий, и я работаю с затмением.

У меня есть проект, в котором есть c-файлы и cpp-файлы. Компоновщик выдает ошибки у меня:

После того как я переименую все *.c файлы в *.cpp ошибки исчезают. Так я не могу смешать эти файлы или это проблема с опциями компилятора / компоновщика?

Мои варианты:

Компилятор GCC C ++:

Компилятор GCC C:

GCC C ++ Linker:

Хорошо, так как он говорит C ++ Linker, означает ли это, что объектные файлы из файлов c не могут быть связаны с проектом (по умолчанию)?

Решение

extern «C» это один подход. Другой подход, предполагающий, что ваши C-файлы имеют (почти повсеместный) вид, который уже компилируется как C ++, состоит в том, чтобы просто заставить компилятор рассматривать их как C ++ (что дает им подходящее название для работы с вашими C ++-файлами). Для GCC это -x c++ ,

Цукерберг рекомендует:  Web - Как автоматизировать Telegram бота

Другие решения

Вам нужно заворачивать код C вроде так

Лучший способ сделать это, как в этот вопрос StackOverflow , в заголовочных файлах C.

В начале все заголовочные файлы C.

В конце все заголовочные файлы C.

Вопросы программисту C/C++ на собеседовании с ответами

Заметил, что на собеседовании часто задают одни и те же вопросы по программированию. Если бы брали на работу водителя, то некоторые вопросы звучат примерно так:

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

Такое конечно случается далеко не всегда, но первые пару вопросов обычно такого рода («А какую надо давить педаль, чтоб автомобиль остановился?»). Публикую свои ответы на некоторые вопросы для программистов. Вдруг кому пригодится.. Возможно, здесь много ошибок и помарок — при составлении этого списка я не пользовался интернетом. Старался выдать, что знаю сам.

Как можно оптимизировать данный цикл?

Вот таким образом:

В исходном цикле каждый раз происходит вычисление позиции элемента в массиве array . Переписав функцию мы избавляемся от этого вычисления.

В чем отличие std::list от std::vector ?

std::vector — это обертка над обычным С/C++ массивом. Соответственно:

  • если std::vector заполнен, то при добавлении нового элемента, массив удаляется целиком и создается заново с бОльшим размером
  • любой элемент массива можно получить моментально, потому что позиция элемента вычисляется банальным прибавлением индекса к первому элементу ( array[i] = array + i )
  • удаление любого элемента из массива, кроме последнего, приведет к перемещению всех элементов справа от удаляемого на одну позицию влево (при соблюдении некоторых условий, можно воспользоваться хаком)
  • занимает неразрывный блок памяти

std::list — это список элементов, которые связаны между собой указателями prev (предыдущий элемент) и next (следующий элемент). Внутри себя std::list хранит указатель на первый элемент и последний (зависит от реализации). Исходя из этого:

  • чтобы удалить любой элемент, необходимо просто переставить указатели
  • для того, чтобы обратиться к произвольному элементу, необходимо пробежаться от начала или конца (в зависимости от реализации) к искомому
  • каждому элементу выделяется память индивидуально

В языке Java различия между ArrayList и LinkedList практически такие же.

Почему в C++ нужно использовать new вместо теплого лампового malloc() ?

Потому что malloc() тупо выделяет блок памяти и возвращает этот блок программисту. А new выделяет память и вызывает конструктор объекта. Тоже самое относится к delete и free() . delete вызывает деструктор и освобождает память. free() просто освобождает память. Также есть размещающий new, который создает объект в уже выделенной вами памяти.

Кстати, изначально конструкторы и деструкторы классов в C++ назывались new и delete и выглядели вот так:

В чем отличие между new/delete и new[]/delete[] ?

new выделяет память для одного элемента и вызывает конструктор для него, в то время как new[] выделяет память для массива элементов и вызывает конструктор для каждого из них. delete должен вызываться для объекта выделенного с помощью new , а delete[] для массива, выделенного с помощью new[] . От проблем соответствия new/delete вас могут избавить классы std::auto_ptr (для одного элемента) и std::tr1::scoped_array (для массива элементов). Которые сами вызывают правильный delete в деструкторе.

Для чего нужен тип std::auto_ptr ?

В стародавние времена вы должны были сами следить за тем, чтоб после каждого new был вызван свой delete . Это было жутко неудобно (программисты Си выкручиваются из этой ситуации вставляя goto ):

bool func() < Stream *stream = new Stream; if (0 != stream->open(«some stream»)) < delete stream; return false; >if (0 != stream->load()) < delete stream; return false; >// Выполняем полезную работу // Закончили полезную работу delete stream; return true; >

После появление std::auto_ptr стало возможным переписать функцию таким образом:

И еще очень важный момент: std::auto_ptr владеет объектом единолично. Вы не сможете шарить объект между двумя std::auto_ptr (используйте в таких случаях std::shared_ptr ):

vo > ptr1(object); // object теперь живет внутри ptr1 std::auto_ptr ptr2(ptr1); // ptr1 опустел, object внутри ptr2 // здесь деструктор ptr2 удалит object // а здесь вызовется деструктор ptr1 впустую >

И помните: std::auto_ptr не подходит для массивов выделенных с помощью new[] . Для этих целей используйте std::tr1::scoped_array или boost::scoped_array .

Что такое RAII?

Это переводится как «Получение ресурса есть инициализация». Идея вкратце такая: в конструкторе открываем/блокируем ресурс, в деструкторе закрываем/освобождаем ресурс. Вот пример:

Или более каноничный пример (блокирование мьютекса или критической секции):

Зачем нужен виртуальный деструктор?

Попробуем обойтись без него:

construct A construct B destruct A

Как можно заметить деструктор B не вызвался. Сделаем деструктор класса A виртуальным и посмотрим что получится:

Теперь все отлично:

construct A construct B destruct B destruct A

В каком порядке инициализируются члены класса?

Члены класса создаются в порядке их объявления в классе. Уничтожаются они в обратном порядке. Давайте проверим:

#include class Printer

Printer() < printf("-%s ", n_); >private: const char *n_; >; class A : public Printer < public: A() : Printer("A") < >>; class B : public Printer < public: B() : Printer("B") < >>; class C : public Printer < public: C() : Printer("C") < >>; class Test < private: A A_; B B_; C C_; >; int main()

Порядок объявления очень важен, если один член класса во время инициализации использует данные другого члена. Кстати, компилятор gcc выдает warning (с флагом -Wall), если вы описали инициализацию членов класса в другом порядке. И это еще одна причина в пользу использования настройки компилятора «считать предупреждения ошибками» (в gcc это флаг -Werror ).

задан массив символов вывести на печать те из них которые являются символами!

Странное ТЗ. Решение: поскольку это массив символов, то каждый элемент массива является символом, значит надо вывести все элементы. :)

видимо он имел в виду массив типа char и из него выводить только символы, являющиеся буквами )

Евгений, спасибо за интересную статью!

Я вот хожу на собеседования (и успешно их проваливаю кстати, т.к. ++ для меня, увы, новый язык, хотя и очень интересный)

Но тем не менее, у меня сложилось впечатление что на собеседованиях требуются более подробные ответы (даже на джуниор)(или я ошибаюсь, и это мне так «повезло»).

Поэтому, если у Вас есть новые примеры вопросиков с собеседовний, то пожалуйста, обновите статью (т.к. вы очень хорошо пишите и разбираете, читатели будут благодарны)

Так же я заметил, что в инете — много теоритических вопросов с краткими ответами, но я пока не находил примеров тестовых задач для собеседований Си++.. Вот если у вас такие имеются — то очень здорово было бы выложить их (хотя бы сами задания (без решения) (а лучше с решением ;) )

Вот например в 2gis, перед приглашением на собеседование — дают задачу (тестовое задание перед собеседовнием) напечатать чек сумму файла (там тематика машинного слова и порядка байтов встречается), так же программа может считать кол-во слов в файле и смещение слов в файле (видимо это для того что бы можно было сделать один базовый класс и 3 производных класса для чексуммы, подсчета и смещений) ну и парсинг аргументов — например если делать свой — то поставят минус за этот пункт, если использовать gnu getopt (поставят +/- — т.к. не свой но и не ооп) — ну а как правильно я не знаю (предполагаю что boost::program_options)

Спасибо за добрые слова!

Статья написана в далеком 2012 году под впечатлением от походов на собеседования. Каждый раз, после начала нашего общения с тимлидом, практически сразу был вопрос: чем отличается std::vector от std::list (а в голове в этот момент: «ну йоп твою мать, шо опять?!»).

На текущем месте работаю уже шестой год подряд, на собеседования не хожу, поэтому не знаю как там сейчас. Наверно, сейчас в моде стандарт C++11x.

Цукерберг рекомендует:  Vkapps - Создание собственного приложения в ВК

Имейте ввиду, что процесс собеседования не всегда подразумевает собой, что вас собираются брать. Иногда собеседование проводится, чтобы тимлид почувствовал себя умнее, чем есть на самом деле. Унизил пару человек никому не нужными энциклопедическими знаниями — значит день удался. :)

По поводу тестового задания в 2gis могу сказать следующее: сложно угадать, что ждет от тебя именно этот тимлид (скиньте задание мне на почту, если вас не затруднит).

Одному нравится вставлять всегда и везде boost, который весь такой шаблонный и C++11x (ждать компиляции часами и героически бороться с разбуханием кода), другому нравится использовать легкие сторонние си-библиотеки (между прочим GNU getopt не кросс-платформенный, поэтому Win32 идет лесом), третий хочет разбор командной строки своими силами и чтоб при этом не было аллокаций памяти (и еще учитывать порядок байтов и юникод), четвертому нравится девственно чистый WinAPI и функции с 15-ю аргументами лесенкой.

Каждый тимлид сходит с ума по-своему, а потенциальную работнику надо предугадать что хочет именно этот чувак.

Спрашивайте, что вас конкретно интересует и я постараюсь ответить (я ведь только с виду такой умный, на самом деле — нет).

может надо было спросить что не так с ответом у того кто проводил тестирование?

Полезные приёмы и хитрости C++

Знать специфику языка, на котором пишешь, всегда полезно. Чем большим количеством особенностей языка владеет разработчик, тем осознанней его код при прочих равных условиях. В материале рассмотрены интересные приёмы и трюки для C++.

Прим. перев. Стоит отметить, что статья в первую очередь будет полезна для олимпиадного программирования. В продакшне некоторые из этих приёмов могут не оценить.

Общие хитрости для C++

1. Макрос watch — один из самых полезных приёмов.

При отладке кода watch(переменная) выведет имя переменной и её значение.

2. Другие полезные макросы:

3. Не бойтесь использовать typedef .

Порой что-нибудь вроде set

>>> можно заменить на set

4. В качестве наиболее точного значения числа π можно использовать const double pi = 2 * acos(0.0) . Желательно использовать именно такой вариант, если иное значение не указано в условии задания.

4 октября 2020 – 1 марта 2020, Москва и онлайн, беcплатно

5. Никогда не используйте INT_MAX в качестве бесконечности для целых чисел. В некоторых алгоритмах, например, Флойда–Уоршелла, используются значения вроде ∞+w, что приведёт к переполнению при использовании INT_MAX . Вместо этого лучше использовать int oo = 0x3f3f3f3f , поскольку:

  • Это число достаточно большое для задач, связанных с целыми числами;
  • 2 * oo не приведёт к переполнению;
  • Все байты равны, поэтому вы без проблем можете использовать memset(array, oo, sizeof(array)) ;
  • Его довольно легко запомнить.

Однако будьте осторожны: не используйте 0x3f3f3f3f для long long , так как в таком случае фокус уже не пройдёт, и вы потом потратите кучу времени на поиск ошибки.

6. Для double -бесконечности хорошей идеей будет использовать double inf = 1.0/0.0 , поскольку именно так представлено значение бесконечности. У вас не будет переполнения, если вы напишете что-нибудь вроде 2*inf , так как 2*inf равно inf .

7. Существует встроенная функция для нахождения наибольшего общего делителя двух чисел. Это функция __gcd , доступная в заголовочном файле algorithm . Подробней можно почитать здесь.

8. Почти всё о манипуляциях с битами — как установить бит, обнулить бит, быстро умножить/разделить на 2 и т.д. — можно найти здесь и здесь.

9. Не используйте 1 , если x может быть больше 31, так как это неопределённое поведение может привести совсем не к тому результату, который вы ожидаете. Сначала приведите 1 к long long : 1ll .

10. Вместо if(условие) x++ вы можете написать x += условие . Спецификация C не гарантирует, что true равно 1, но в соревновательном программировании можно предположить, что это сработает.

11. Всегда компилируйте код с флагом -O2 . Ваш алгоритм может тратить слишком много времени на работу, однако компилятор сделает свою оптимизационную магию, и вы уложитесь в нужное время.

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

12. Стандартные объекты ввода и вывода C++ cin и cout по умолчанию работают быстро. Но их работу замедляет синхронизация с буферами C. Поэтому, если в начале кода написать ios::sync_with_stdio(false) , то cin и cout будут работать так же быстро, как и printf и scanf , которые вы, однако, больше не сможете использовать.

13. Не стесняйтесь использовать глобальные переменные. Максимальный размер массива, объявленного в функции main , может быть порядка 10 6 , в то время как размер глобального массива может быть порядка 10 7 .

Прим.перев. Ограничение на размер массива, объявленного внутри функции, возникает из-за того, что память, выделяемая операционной системой под стек, ограничена.

Хитрости для GCC

1. Если вы используете GCC, вы можете написать #include для импортирования всех стандартных библиотек.

2. GCC имеет встроенные функции для проведения определённых манипуляций с битами за постоянное время. Например, __builtin_popcount вычисляет общее количество установленных битов заданного целого числа (для long long используйте __builtin_popcountll ).

Есть множество других встроенных функций, прочитать про которые можно здесь.

Хитрости для C++11

C++11 привнёс некоторые обновления и пару классных вещей. Почти все компиляторы установили эту версию по умолчанию, но если в вашем случае это не так, то используйте флаг -std=c++11 для компиляции.

Прим. перев. В новых версиях GCC по умолчанию включён более новый стандарт C++14, который включает в себя все возможности C++11.

1. В заголовочном файле numeric есть полезная функция std::iota . Она заполняет std::vector (или какой-нибудь контейнер) увеличивающимися значениями, начиная с x . Например, iota(v.begin(), v.end(), x) .

2. Вам больше не нужно использовать _pair . Вместо этого вы можете написать ii p = <1, 2>или, например, iii p = <1, <2, 3>> .

Примечание Иногда работает не так, как вы ожидаете . Например, этот код выведет то, что должен:

Этот код, с другой стороны, не скомпилируется. Дело в том, что в результате инициализации списка просто инициализируются объекты. Вы не можете использовать их без контекста. Больше подробностей здесь.

3. Ключевое слово auto позволяет не указывать явно тип переменной, если вы объявляете и инициализируете её в одном месте. Например, вместо int i = 10 вы можете написать auto i = 10 , поскольку компилятор знает, что у i тот же тип, что и у 10 . Само собой, без инициализации переменной это не сработает.

4. В С++11 появилась такая классная штука, как цикл for , основанный на диапазоне. Например, вам не придётся писать for (int i = 0; i , потому что теперь есть for (auto &e : v) . За подробностями сюда.

Он очень полезен при обходе std::set или std::map :

Если вы хотите изменять значения, то используйте спецификатор & , чтобы получить ссылку на содержимое контейнера.

5. Вы можете написать функцию, которая будет возвращать два и более значений, с помощью std::tuple и std::tie .

Уже знали все эти хитрости и думаете, что вы эксперт в С++? Тогда пройдите наш тест и подтвердите это.

C++ — Помогите решить вопрос в C++ пожалуйста!

Сообщения: 121
Благодарности: 35

Думаю модификатор const в этой задачке не нужен. »

Если так рассуждать, то он вообще не нужен. Однако, если какое то значение не изменяется на протяжении программы, то его принято определять как константу. Не стоит пренебрегать такими, казалось бы, незначительными правилами. Их соблюдение помогает сделать программу более читаемой и избежать дополнительных ошибок.

У вас более профессиональная программа с применением массива. »

Более профессиональная не столько из-за применения массива, сколько из-за смысла его применения. Если в задаче изменить числовые данные (например, 10 чисел и интервал (0.5, 8.6)), то будет достаточно изменить значения констант, а алгоритм останется прежним. Кстати, вы благополучно убрали такую возможность жестко задав длину массива.

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих