Недавно начал изучать 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"
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости