Недавно начал изучать C++, столкнулся со странной конструкцией условного оператора и не могу понять что он с чем сравнивает
у нас два массива с типом char одинаковой длины, далее он как-то сравнивает символы этих массивов. И главный вопрос: какие символы должны быть в mas[], чтобы длина строки осталась той же, но условие не выполнилось
char mas[] = "qwerty";
char a[] = "J@RODQ";
for (int i = 0; i < sizeof(a)-1; i++) {
if (mas[i] - !!a != a[i]) { // что с чем сравнивается?
puts("WRONG!");
return -1;
}
}
Конструкция верная, но бессмысленная с практической точки зрения. Подвыражение !!a
- это применение двух операторов !
к массиву a
. В этом контексте массив неявно приводится к типу "указатель" (получается ненулевой указатель), а затем к типу bool
(ненулевой указатель превращается в true
). Двойное применение логического отрицания !
к значению true
снова дает true
. Таким образом значение выражения !!a
- просто true
. В арифметическом контексте true
ведет себя эквивалентно значению 1
, то есть ваше условие эквивалентно
if (mas[i] - 1 != a[i])
Вот и все. Остальной код никакими особенностями не обладает. Почему автор написал !!a
вместо просто 1
- неизвестно. Скорее всего просто для обфускации кода.
Чтобы условие ни разу не выполнилось, надо поместить в строку mas
символы, коды которых на единицу больше соответствующих кодов символов строки a
char mas[] = "23456";
char a[] = "12345";
Как будет выглядеть строка mas
для вашего исходного варианта a
- формально зависит от платформы. Можно записать ее так
char a[] = "J@RODQ";
char mas[] = { a[0]+1, a[1]+1, a[2]+1, a[3]+1, a[4]+1, a[5]+1, 0 };
Char это числовая переменная.
a
- указатель. В C ++ значение nullptr определено как недопустимый указатель. ! Pointer
превращает указатель nullptr в true и указатель non nullptr в false. ! Boolean
превращает true в false и false в true. Он всегда будет работать.
Не думайте, что это «двойной восклицательный знак», думайте об этом как о двух отдельных операторах, один из которых работает на результат другого.
!(!a)
Взлом простым перебором:
#include <string>
#include <iostream>
void check(const char* mas){
char a[] = "J@RODQ";
for (int i = 0; i < sizeof(a)-1; i++) {
if (mas[i] - !!a != a[i]) {
puts("WRONG!");
return;
}
}
puts(mas);
}
int main(){
std::string answer = "";
char a[] = "J@RODQ";
for (int i = 0; i < sizeof(a)-1; i++) {
for(int c=0;c < 1000;c++){
if (c - !!a != a[i]) {
} else {
answer += c;
break;
}
}
}
check(answer.c_str());
}
P.S. Онлайн компилятор: https://repl.it/I4y0/4 Ответ: "KASPER"
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
У меня есть класс основного окна MainWindowС него я запускаю (допустим, при авторизации) модальное окно авторизации с полями "Логин", "Пароль" (lineLogin,...
Всем добрый деньСтандартный конструктор копирования в классе выглядит так: SomeClass(const SomeClass &obj) Как я понимаю, const отвечают за то, что в процессе...