Страницы

Поиск по вопросам

понедельник, 15 апреля 2019 г.

Пул констант в Java

Не раз слышал о так называемом пуле констант в языке программирования Java. Знаю о пуле объектов типа String, пуле для типов Byte, Short, Character, Integer, Long и даже Boolean. Также знаю, что мы сами можем определять размер пула типа Integer, если запускать приложение с параметром -Djava.lang.Integer.IntegerCache.high=XX, где XX может колебаться в диапазоне от 127 до (Integer.MAX_VALUE - 129). Весь этот пул представляет собой массив, каждое значение которого является элементом расположенным в порядке числового возрастания и мы можем напрямую обратиться к нему по индексу за константное время O(1). Я прекрасно понимаю, где хранится этот массив. У каждого целочисленного обёрточного типа есть свой вложенный класс такого типа:
private static class WrappingСlassNameCache {...}
Где вместо WrappingСlassNameCache, мы подставляем конкретное имя класса, к примеру, IntegerCache. Внутри это выглядит так:
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[];
static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h;
cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; }
Ну Бог с ним, тут ничего мудрёного нет! А что же такое пул констант? Что он из себя представляет? И вообще где хранятся все константы в Java? Если мы говорим о локальных финализированных переменных, то они хранятся в стековой памяти. Если мы имеем дело со static final полями, то эти поля хранятся в MetaSpace (раньше в PermGen), если мы говорим о реализации JVM HotSpot. Так о каком вообще пуле может идти речь? Как всё это реализовано? Описано в каком-то классе, который поставляется вместе со стандартным API от Oracle (раньше Sun Microsystems) или же это нужно заглядывать в реализацию конкретной JVM и читать JVMS? Подскажите, пожалуйста, надоело, что в которой раз сталкиваюсь с этим понятием и никак не могу понять о чём идёт речь. Всем огромное спасибо за помощь! :)


Ответ

У каждого класса свой пул констант. Чтобы понять для чего он нужен, разберём простой пример
class Example { public void hello() { System.out.println("Hello"); } }
Скомпилируем
$ javac Example.java
И заглянем внутрь
$ javap -c -v Example.class
public class Example minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #6.#14 // java/lang/Object."":()V #2 = Fieldref #15.#16 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #17 // Hello #4 = Methodref #18.#19 // java/io/PrintStream.println:(Ljava/lang/String;)V #5 = Class #20 // Example #6 = Class #21 // java/lang/Object #7 = Utf8 #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 hello #12 = Utf8 SourceFile #13 = Utf8 Example.java #14 = NameAndType #7:#8 // "":()V #15 = Class #22 // java/lang/System #16 = NameAndType #23:#24 // out:Ljava/io/PrintStream; #17 = Utf8 Hello #18 = Class #25 // java/io/PrintStream #19 = NameAndType #26:#27 // println:(Ljava/lang/String;)V #20 = Utf8 Example #21 = Utf8 java/lang/Object #22 = Utf8 java/lang/System #23 = Utf8 out #24 = Utf8 Ljava/io/PrintStream; #25 = Utf8 java/io/PrintStream #26 = Utf8 println #27 = Utf8 (Ljava/lang/String;)V { public Example(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return LineNumberTable: line 1: 0
public void hello(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String Hello 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 3: 0 line 4: 8 }
Первое, что представляет интерес - это байткоды метода hello
0: getstatic #2 3: ldc #3 5: invokevirtual #4
Цифры до двоеточия обозначают байт, с которого начинается байткод и его параметры. По шагу видно, что каждая операция - это два байта, один байт на код операции и один байт на параметр. Байткоды могут принимать только параметры фиксированного размера - integer, long, short, byte, character, float, double, reference. Чтобы передать в метод println строку "Hello", надо загрузить в стек ссылку на строку "Hello", а саму строку где-то сохранить. Вот это где-то как раз и есть пул констант. А символы #3 после байткода ldc - ссылка на 3-й элемент в пуле констант.
Constant pool: #1 = Methodref #6.#14 // java/lang/Object."":()V #2 = Fieldref #15.#16 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #17 // Hello #4 = Methodref #18.#19 // java/io/PrintStream.println:(Ljava/lang/String;)V
Как можно увидеть из этого кусочка пула, его элементы сами часто ссылаются в пул. В частности наша строка под номером 3 ссылается на массив символов под номером 17.
Если говорить о расположении пула констант в памяти JVM, то это один из участков MetaSpace.

Хорошая ли практика создавать свои классы Exception для отлавливания разных ошибок?

Я только недавно изучил механизм Exception'ов и сейчас их осваиваю. Вот пара вопросов по поводу их применения:
Можно ли создавать свои пустые классы Exception'ов наследуемые от класса Exception только лишь для того что бы было отдельное имя исключения? Например: я работаю с файлами, и если файл не удалось загрузить файл - я бросаю исключение
throw new FileException('Не удалось загрузить файл')
Сам класс `FileException ничего не содержит
class FileException extends \Exception { //empty! }
И второй вопрос, который вытекает из первого. Делаю я это для того что бы отловить различные ошибки. Например при добавлении сообщения на сайте, у меня может возникнуть разные исключения, например: Не корректное сообщение, Не удалось загрузить файл, ошибка PDO. То есть в контроллере это будет выглядеть так:
public function actionMethod() { try { //some code; } catch (FileException $e) { echo 'С файлами что то пошло не так:' . $e->getMessage(); } catch (MessageException $e) { echo 'С сообщением что то пошло не так:' . $e->getMessage(); } catch (PDOException $e) { echo 'С БД что то пошло не так:' . $e->getMessage(); } catch (Exception $e) { echo 'Что то совсем пошло не так :('; } }
Можно ли так делать? Это нормально что в контроллере столько много catch'eй? На сколько это хорошая практика? Или я не правильно понял механизм работы исключений?


Ответ

Нужны ли исключения для каждой ошибки отдельно?
Отвечая на вопрос
При добавлении сообщения на сайте, у меня может возникнуть разные исключения: Не корректное сообщение, Не удалось загрузить файл, ошибка PDO. Нужны ли исключения для каждой ошибки отдельно?
Нужно исходить из следующего:
что даст текст исключения для пользователя что даст разработчику
Не корректное сообщение Не удалось загрузить файл
Это стоит отдать в браузер, чтобы пользователь понял свою ошибку и исправил ее. Старайтесь сделать такое сообщение понятным. "Не удалось загрузить файл. Используйте разрешенные форматы (docx, xlsx)"
ошибка PDO
Особенности работы сайта пользователю знать не нужно. Запишите себе в журнал, и сообщите "Ошибка сервера, попробуйте чуть позже". Может видели сообщения у Гугла и Яндекса а-ля "что-то сломалось, но мы уже знаем".
// глобальный отлов ошибок try {
try { throw new Exception("DB error"); } catch (Exception $e) { // Я люблю в качестве кодов ошибок использовать 400-е и 500-е HTTP коды $errCode = $e->getCode() if($errCode >= 500) { syslog(LOG_ERR, '[Sign][docs.list][error]MySQL is gone away'); http_response_code($errCode); throw new Exception("Ошибка сервера, попробуйте чуть позже"); } }
} catch (Exception $e) { // выводим ошибку пользователю }
Кстати, писать можно в syslog, его PHP-программисты почему-то незаслуженно забыли. А если к сислогу прикрутить что-то типа ELK, то можно отслеживать динамику ошибок и настроить уведомления.
Удобно, если ошибка произошла где-то в глубине
Если в каком-то глубоко вложенном методе что-то пошло не так, то бросить исключение - как экстренное всплытие. Это лучше, чем назад по цепочке возвращать null/false. Ваш код станет чище.
Использование исключений как способ построения логики вместо if ... else ...
Пример:
try { // пробуем получить координаты по картам Гугла $this->geoPositionGoogle($data); } catch (Exception $e) { // если не получилось, пробуем по картам Яндекса $this->geoPositionYandex($data); }
Защитное программирование
Его суть - в проверке пришедшего и ожидаемого значений. Я использую чаще всего в двух случаях:
много потенциальных точек возникновения ошибок. У меня это электронная подпись документов (может отказать сеть, база, скрипт подписания, и так далее). Подробный отчет об ошибках значительно облегчает диагностику проблем взаимодействие с внешними сервисами, где что-то может измениться без ведома программиста
Пример обмена с 1С:
switch($row['SECTION_TYPE']) { case 'directionBonus': // Ожидается, что название будет начинаться со слова "Бонус" if(!preg_match('~^Бонус\s+(.*)$~i', $row['SECTION_NAME'], $m)) throw new Exception("Wrong name"); break; case 'groupDDP'; // Ожидается, что название будет начинаться с кода раздела if(!preg_match('~^([0-9]+\.[0-9]+\.[0-9]+)\s+(.*)$~i', $row['SECTION_NAME'], $m)) throw new Exception("Wrong name"); break; default: // Ожидается, что других вариантов нет throw new Exception("No such case"); }
Хорошая ли практика создавать свои классы Exception для отлавливания разных ошибок?
Хорошая, но не увлекайтесь. Делайте минимум. Если будет больше, начнете путаться и зависать, решая, какое исключение больше подходит.
Хорошая статья

Как поставить програмную точку останова

Как поставить програмную точку останова в разных языках средах и IDE. Часто вижу вопросы не могу отладить программу потому что программа большая, обьёмы большие. Цикл на 10000000. Такие ситуации можно отловить, например, при возникновении ошибки у меня i=357489, а не понятно почему возникло исключение, тогда делаем, напимер так:
for (i=0;i<10000000;i++) { if (i==357489) DebugBreak(); // код }
Но DebugBreak - функция windows. Как можно поставить точки останова в других средах?


Ответ

В с с++ есть такие варианты поставить точку останова
DebugBreak(); - среда windows __builtin_trap() - среда linux raise(SIGTRAP) - работа с сигналами POSIX posix __EMIT__(0xCC) или __emit__(0xcc); - некоторые среды поддерживают вставку кода __asm { int 3;} или __asm { db 0xCC;} ассемблерная вставка
Для других сред
с# System.Diagnostics.Debugger.Break(); javascript debugger; java try {throw new TurnOnDebuggerException();}catch(TurnOnDebugger td) {/*Nothing*/ } pascal inline($CC); vbscript visual-basic stop

Как прилинковать нестандартную версию protobuf используя cmake

Есть проект под arm который компилируется и собирается на х86ой машине (кросскомпиляция). Есть версия библиотеки protobuf собранная под arm по этой инструкции. В cmake файле я пытаюсь явно указать местоположение собранной под arm библиотеки через переменную Protobuf_SRC_ROOT_FOLDER но похоже что cmake эта переменная вообще побоку. Что мне сделать что бы find_package(Protobuf REQUIRED) нашёл ту версию protobuf которая мне нужна?
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -pthread ") #-lboost_system project(proto_test)
# Подключаем протобуф set (Protobuf_SRC_ROOT_FOLDER "/home/mrfieldy/prot_build/protobuf-3.5.1-arm/src") #set (Protobuf_USE_STATIC_LIBS ON) find_package(Protobuf REQUIRED) include_directories(${PROTOBUF_INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS test.proto) add_executable(${PROJECT_NAME} test.pb.cc ${PROTO_SRCS} ${PROTO_HDRS} "main.cpp") target_link_libraries(${PROJECT_NAME} ${PROTOBUF_LIBRARIES})

Ответ:
В общем, как посоветовали ниже, я выбрал путь сначала выполнить find_package, а потом с помошью set переопределить пути. Долго искал на какие пути надо переопределить. Вот рабочий вариант.
cmake_minimum_required(VERSION 2.8) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -pthread ") project(proto_test) # Подключаем протобуф find_package(Protobuf REQUIRED) set (PROTOBUF_INCLUDE_DIRS "/home/mrfieldy/prot_build/protobuf-3.6.0-arm/src/") set (PROTOBUF_LIBRARIES "/home/mrfieldy/prot_build/protobuf-3.6.0-arm/src/.libs/libprotobuf.so") include_directories(${PROTOBUF_INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) #protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS test.proto) add_executable(${PROJECT_NAME} test.pb.cc ${PROTO_SRCS} ${PROTO_HDRS} "main.cpp") target_link_libraries(${PROJECT_NAME} ${PROTOBUF_LIBRARIES})


Ответ

Поискал по переменной Protobuf_SRC_ROOT_FOLDER и нашел вот что:
FindProtobuf
К сожалению мой английский sehr schlecht, но, насколько я понял у вас версия cmake слишком низкая (документация там начинается с 3.02), а сама переменная касается лишь определенного случая, касающегося Visual Studio и, что-то мне подсказывает, это не то, что вы используете.
Посоветую написать Find-файл самому - это довольно просто

Использование this в return

Есть код подобного вида:
function test() { return { foo: 2, bar: 3, value: this.foo + this.bar } }
Почему this не ссылается на нужный объект?


Ответ

Вычисление выражения this.foo + this.bar происходит в контексте функции test. Вы не можете в момент создания нового объекта обращаться к его свойствам.
Добиться похожего результата можно так:
function test() { return { foo: 2, bar: 3, get value() { return this.foo + this.bar; } }; } console.log(test().value);
В таком случае значение свойства value будет вычисляться динамически.

Синтаксис классов/структур c++

Имеется такой класс для, например, вывода вектора через библиотеку algorithm. Объясните по какому принципу myobject работает в коде и что это вообще такое?
struct myclass { void operator() (int i) {std::cout << ' ' << i;} } myobject;
for_each (myvector.begin(), myvector.end(), myobject);


Ответ

Шаблонная функция std::for_each внутри себя пробегает в цикле по всему диапазону итераторов, который вы ей передали: от myvector.begin() до myvector.end() и для каждого итератора it в этом диапазоне выполняет следующее выражение
myobject(*it) Компилятор видит, что myobject - это не функция, а экземпляр некоего класса myclass. В такой ситуации компилятор расценивает выражение myobject(*it) как вызов
myobject.operator()(*it)
А это и есть вызов вашего метода класса с аргументом *it, т.е. с очередным значением из вектора.

zipfile не распаковывает архив

# -*- coding: utf-8 -*- import zipfile root = "C:" z = zipfile.ZipFile(root + '\\ProgramData\\boot//s0urc3.zip','r') z.extractall()
Все выполняется без ошибок, но архив не распаковывается, почему?


Ответ

Файлы распаковываются в текущую рабочую папку. Добавьте в начало скрипта:
import os print os.getcwd()
Это покажет вам рабочую папку (обычно это папка, где лежит запускаемый скрипт) и там будут распакованные файлы
А в конец скрипта добавьте
z.close()
Чтобы указать папку, куда нужно сохранить, нужно передать ее в качестве параметра:
path_to_extract = 'C:\\Data' z.extractall(path_to_extract)
Если в этой папке окажутся файлы с именами, совпадающими с файлами в архиве, они будут перезаписаны без предупреждения

системы сборки c++ в qt

Переустановив qt (звучит как прям история,minGW для qt на windows 64-bit(и не только)) и отогнав сомнения насчет minGW я захотел в qt creator написать hello world...
И тут задумался:что за системы сборок? Пользовался qmake(потому что по дефолту стояла).
Короче можете простыми словами объяснить что такое qmake,Cmake,Qbs...Пожалуйста


Ответ

qmake - система сборки, родная для Qt. Не знаете что использовать - берите ее. Нативно работает с QtCreator. Cmake - популярная система сборки. Умеет собирать разнообразные проекты под разнообразные оси/среды разработки. Умеет собирать и Qt проекты, но требует немного "телодвижений". QtCreator умеет с ней хорошо работать, но иногда как то оно странно (но может это мне везет). qbs - попытка "исправить qmake", написать все заново и правильно. Также всякие новомодные штуки - json подобный стиль файла проекта, модули, сборки под разные оси. почитать холивора на lor от самий разработчиков Qt статистика

Как “присвоить” функцию в переменную?

Здравствуйте как "присвоить" функцию в переменную:
Есть мат. функции: int sum(a,b); int sub(a,b); int div(a,b)
Есть код:
void main(){ operation = sum; }
var operation; int calc(a,b) { ... operation(a,b); ... }
P.S. Я знаю, как передать функцию в виде аргумента, но тут другая ситуация и нужно именно функцию "присвоить" переменной.


Ответ

Чтобы присвоить функцию переменной, нужно чтобы переменная имела тип делегата, который описывает в точности такую же сигнатуру функции.
Вот пример с двумя вариантами:
class Program { //Можно явно создать делегат, описывающий нужную сигнатуру delegate int MathOperation(int a, int b); //И использовать его как тип static MathOperation Operation1;
//Либо не создавать явно делегат, а использовать Func static Func Operation2;
static void Main(string[] args) { Operation1 = Sub; var sub = Operation1(10, 5);
Operation2 = Sum; var sum = Operation2(10, 5); }
static int Sub(int a, int b) { return a - b; }
static int Sum(int a, int b) { return a + b; } }

Непонятная ситуация с приложением android

У меня есть приложение для андроид с определенным функционалом, одной из функций является логин при помощи retrofit, для того что-бы как-то продолжить работу с приложением после удачной авторизации, я сделал переход на другое активити например назовем ее seconscreen. То есть если мы вводим правильно пароль и логин то после нажатия на кнопку переходим на второе активити. В андроид студии есть такая функция как Build APK, для того что-бы создать файл-установщик программы. Я воспользовался данной функцией и создал данный файл. Потом я эту программу поставил на реальное устройство для проверки его работы, и вот что меня просто ОЧЕНЬ удивило, так это то что после установки у меня появилось вместо одного приложения, два а именно приложение с функцией логина, где мы можем залогинится и перейти на второй экран, и второе приложение которое состоит только из активити SeconScreen. Я не понял в чем причина такой странной инсталяции если честно. Может кто сталкивался с подобной ситуацией и знает в чем причина, буду очень благодарен за помощь и содействие в решении моего вопроса.


Ответ

У вас в манифесте несколько Activity помечены как LAUNCHER

Только для основной Activity указывайте его:

Повторы строк php

Есть код, который выводит цвета:


Из базы я получаю полностью весь продукт. А цвет содержится в одном поле в формате: ссылка на картинку___Цвет;ссылка на картинку___Цвет;ссылка на картинку___Цвет
В итоге получаем:
Синий Белый Синий Красный Черный
Как вы видите, здесь два "Синий". Как сделать, чтобы выводится только первый "Синий"? Спасибо.


Ответ

$array = [];
if (!in_array($color[1], $array)) { $array [] == $color[1]; // массив с цветами // добавляем только разные цвета }

Определить сигнатуру функции

Как в C++ определить сигнатуру функции, переданной в шаблон другой функции? Делаю так:
#include
template struct Signature;
template struct Signature { using RetType = R;
using Arguments = std::tuple; };
template void test(Func f) { using Sig = Signature; Sig s; //Error: Sig - undefined struct }
double square(double x) { return x * x; }
int main() { using Sig = Signature; Sig s; //ok test(square); }
Вот что меня смутило в логе компиляции:
error C2079: 's' uses undefined struct 'Signature' with [ Func=double (__cdecl *)(double) ]
Появилось (__cdecl *). Что оно вообще означает, и как тогда определить сигнатуру в test(Func f)?


Ответ

Надо добавить специализацию для указателя на функцию:
template struct Signature { using RetType = R;
using Arguments = std::tuple; };
Это нужно потому, что после передачи функции в качестве параметра в test она неявно преобразуется в указатель и тип Func будет на самом деле указателем на функцию.

Как конвертировать цвет пикселя ABGR в ARGB?

ARGB getPixelColor(HWND hWnd, int x, int y) { HDC dc = GetDC(hWnd); ARGB color = GetPixel(dc, x, y); ReleaseDC(hWnd, dc); return color; }
использую эту функцию получаю значение ABGR например 0x000248ac но мне нужно ARGB 0x00ac4802 подскажите как мне "инвертировать" это значение?


Ответ

uint32_t ABGR_to_ARGB(uint32_t abgr) { uint32_t tmp = ((abgr >> 16) ^ abgr) & 0xFF; return abgr ^ ((tmp << 16) | tmp); }
Другой вариант (ссылаясь на ответ от @Maxim Egorushkin здесь)
uint32_t ABGR_to_ARGB(uint32_t abgr) { uint32_t grab = abgr >> 16 | abgr << 16; return (abgr & 0xFF0FF00) | (grab & 0x00FF00FF); }
Если ваш компилятор достаточно умен для того, чтобы сообразить, что abgr >> 16 | abgr << 16 - это ни что иное как циклический сдвиг abgr на 16, то этот вариант странслируется в очень компактный машинный код на платформах с инструкцией циклического сдвига.

Как устроены примитивные типы в Java?

Типы-обёртки (вроде Integer) это классы, которые вполне можно "пощупать" в исходниках и понять как они устроены и работают. Как реализованы примитивные типы на уровне языка?


Ответ

Честно говоря опасаюсь, что не понимаю суть вопроса, но ответить всё же попробую. Возьмём для примера
public class Example { public static void test() { int i = 69; }
public static void main(String[] args) { test(); } }
После компиляции исходный код превратится в class-файл содержащий байткод - инструкции виртуальной машины. В частности int i = 69 превратится в два байткода
0: bipush 69 2: istore_0
Команда java Example запустит виртуальную машину, которая загрузит файл Example.class в память, создаст главный поток и вызовет в нём метод main. При создании главного потока в off-heap памяти виртуальной машины для него будет создан стек. В момент вызова метода test в этом стеке будет создан фрейм. Каждый фрейм содержит массив 32-битных ячеек для хранения локальных переменных и аргументов метода, а также стек операндов. Да-да, стек в стеке. JVM - стековая виртуальная машина, в ней стек операндов служит тем же целям, что и регистры в процессоре. Виртуальная машина начнёт выполнять байткод метода с нулевого смещения, по которому расположен опкод bipush с операндом 69. Этот опкод поместит константу 69 на вершину стека операндов. Следующий опкод istore_0 возьмёт элемент с вершины стека операндов и поместит в 1-й элемент массива локальных переменных.

"Пощупать" релизацию виртуальной машины, выполняющей байткод можно так же в исходниках. Правда, это будет уже C++, а не Java. Посмотреть код интерпретатора, выполняющийся для конкретного опкода, можно там же, но он платформозависим и в нём уже будет сплошной ассемблер.

switch case C++

Почему этот код не работает? Неужели в C++ switch не принимает тип string это же чушь какая-то.
string text; cin>>text; switch(text){ case "n": std::cout << "Some output"; break; default: std::cout<<"Input incorrect!"; break; } return 0;


Ответ

string нельзя использовать в switch. Кажется, char* можно, но бесполезно. А вот char - вполне пойдёт, правда, в таком случае все строки, начинающиеся на n будут подходить под условие.
string text; cin>>text;
switch (text[0]) { case 'n': std::cout << "Some output"; break;
default: std::cout<<"Input incorrect!"; break; }
return 0;