Найдите ошибку в коде
12 255
17 ноября 2016 в 16:45
Простая задача, но все же требует внимательности, а также знаний в программировании. Итак, я дам вам небольшой кусочек кода, а вы скажите в чем здесь ошибка.
Вот сам код:
unsigned int i;
for (i = 100; i >= 0; --i)
printf("%dn", i);
В этом коде есть две небольшие ошибки, которые вам стоит найти.
Ошибки
Первым делом, стоит обратить внимания на неправильное определения переменной i
. Дело в том, что в данном случае оно является неверным. Тип unsigned int
говорит о том, что значения этой переменной могут быть только цифры, при чем только положительные цифры без знака минус. Данная запись приводит к тому, что цикл будет выполняться вечно, так как условие всегда будет истинным (true).
Корректный код состоял бы из такого условия i > 0
. Он мог бы вывести все значения, кроме нуля. Цикл завершился бы и тогда мы могли бы после самого цикла прописать еще и вывод 0
. К примеру, у нас бы получилось нечто вроде этого:
unsigned int i;
for (i = 100; i > 0; --i)
printf("%dn", i);
printf("%dn", i);
Вторая ошибка намного проще и заключается в том, что мы используем %d
вместо того чтобы использовать %u
. Поскольку мы выводим числа без минуса, то именно так должно все быть. В итоге у нас получился вот такой код, который верно выводит значения от 100 до 1:
unsigned int i;
for (i = 100; i > 0; --i)
printf("%un", i);
Больше интересных новостей
В этой части «Найди ошибку» компонент ToDoList
, принимает массив элементов и отображает их в виде списка. Однако в коде есть небольшая ошибка:
import React from "react";
const ToDoList = ({ items }) => {
return (
<div>
<ul>
{items.length && items.map(item => <li key={item.id}>{item.text}</li>)}
</ul>
</div>
);
};
const App = () => {
return (
<div>
<h2>Сегодня:</h2>
<ToDoList
items={[
{ id: 1, text: "Полить цветы" },
{ id: 2, text: "Помыть машину" },
{ id: 3, text: "Выкинуть мусор" },
]}
/>
<h2>Завтра:</h2>
<ToDoList items={[]} />
</div>
);
};
export default App;
Решение
Если вы запустите код, вы заметите, что список дел на завтра отображает 0.
Это связано с тем, как JavaScript обрабатывает оператор &&
. В React &&
обычно используется для условного рендеринга, если левая часть оператора &&
является ложной, тогда оператор &&
останавливает дальнейшее вычисление выражения.
true && "hello world" // "hello world" will be rendered
false && "hello world" // nothing will be rendered
Это работает, потому что React ничего не отобразит для логического значения false
. Однако проблема с компонентом ToDoList
заключается в том, что мы проверяем items.length
, который возвращает 0
, если элементов нет, что React отобразит как допустимый фрагмент JSX.
Как это исправить?
Самое простое решение — всегда использовать тернарный оператор при условном рендеринге в React:
import React from "react";
const ToDoList = ({ items }) => {
return (
<div>
<ul>
{items.length
? items.map((item) => <li key={item.id}>{item.text}</li>)
: null}
</ul>
</div>
);
};
const Apps = () => {
return (
<div>
<h2>Today:</h2>
<ToDoList
items={[
{ id: 1, text: "Полить цветы" },
{ id: 2, text: "Помыть машину" },
{ id: 3, text: "Вынести мусор" }
]}
/>
<h2>Tomorrow:</h2>
<ToDoList items={[]} />
</div>
);
};
export default App;
Таким образом, вы явно указываете React, что отображать, если левая часть тернарной операции ложна — в этом случае, если элементов нет, мы хотим отобразить null
. Как и ожидалось, для завтрашнего списка дел ничего не отображается.
Это хороший шаблон, поскольку он заставляет вас более думать о ложных случаях в вашем коде. Например, в этом случае было бы неплохо отобразить некоторый текст, сообщающий пользователю, что список дел пуст.
***
В будущем следует обратить внимание на то, что может помочь с условным рендерингом, это выражение do
, которое позволят нам делать что-то вроде этого:
return (
<nav>
<Home />
{
do {
if (loggedIn) {
<LogoutButton />
} else {
<LoginButton />
}
}
}
</nav>
)
В настоящее время do
находится на стадии предложения, но, на мой взгляд, этот способ понятнее и проще в использовании, чем тернарные условия, особенно когда есть несколько вложенных условий.
Спасибо за внимание!
Найдите ошибку: Функциональное Карри
Источник
Время на прочтение
2 мин
Количество просмотров 8.6K
Авторы анализатора PVS-Studio предлагают вам проверить свою внимательность и развлечься. Попробуйте быстро отыскать баг в фрагменте исходного кода и ткнуть в него мышкой.
Анализаторы кода работают без устали и умеют находить множество ошибок, которые сложно заметить. Мы отобрали несколько фрагментов кода, в которых выявили ошибки с помощью PVS-Studio. Все фрагменты взяты из известных Open Source проектов.
Предлагаем вам посоревноваться с анализатором в прозорливости и попробовать самостоятельно найти ошибки. Вам будет предложено 10 случайно выбранных заданий. За верный ответ начисляется одно очко, если баг найден в течение 1 минуты.
Ограничение в 1 минуту сделано для интереса. Иначе вы, скорее всего, верно найдёте и укажете каждую ошибку, так как фрагменты кода короткие. В любом случае относитесь к этому просто как к игре, а не как к настоящему тестированию программистских навыков у вас или ваших коллег
Когда нашли ошибку, выделите её кликом мышки и нажмите кнопку «Ответ». Бывает, что в коде есть сразу несколько мест, куда вы можете «ткнуть» — и ответ зачтётся как правильный. Поясним это на примере.
case FuriHalSubGhzPreset2FSKDev476Async:
preset_name = "FuriHalSubGhzPreset2FSKDev476Async";
break;
FURI_LOG_E(SUBGHZ_PARSER_TAG, "Unknown preset");
default:
Этот код взят из проекта FlipperZero. Анализатор PVS-Studio сообщает, что часть кода никогда не выполняется: V779 [CWE-561, CERT-MSC12-C] Unreachable code detected. It is possible that an error is present. subghz_i.c 44
Кто-то поспешил и использовал макрос логирования после оператора break. Или это следствие неудачного рефакторинга. В любом случае ошибка очевидна, но вот куда именно ткнуть мышкой – вопрос сложнее.
С одной стороны, в качестве ответа можно выбрать оператор break. Он расположен до макроса FURI_LOG_E и прерывает выполнение оператора switch. Значит, проблема здесь.
С другой стороны, можно выбрать макрос логирования. Ведь это недостижимый код.
Так как же быть? Очень просто. В данном случае правильным ответом будет считаться как выделенный оператор break, так и макрос FURI_LOG_E.
Думаем, правила понятны. Желаем вам удачи: начать игру.
Не забудьте, показать этот Quiz вашим коллегам! Развлекайтесь, и безбажного вам кода!
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. PVS-Studio’s challenge: can you spot an error?.
2atlantis 0 / 0 / 0 Регистрация: 09.01.2020 Сообщений: 67 |
||||
1 |
||||
Найдите ошибку в коде20.01.2020, 04:28. Показов 2124. Ответов 10 Метки нет (Все метки)
Бьюсь над задачей
Вот намудрил такой код к ней,но цикл почему то не работает,не считает как надо,пишет что нужное кол-во лет 1, либо превышен срок.Где ошибка,как исправить???
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
20.01.2020, 04:28 |
Ответы с готовыми решениями: Найдите ошибку в коде Найдите ошибку в коде Найдите ошибку в коде с++ Найдите ошибку в коде using namespace std; void main() 10 |
Заблокирован |
||||
20.01.2020, 04:45 |
2 |
|||
Сообщение было отмечено 2atlantis как решение Решение
0 |
2atlantis 0 / 0 / 0 Регистрация: 09.01.2020 Сообщений: 67 |
||||
20.01.2020, 04:52 [ТС] |
3 |
|||
Вроде что-то поменялось но он теперь пишет все года по порядку
0 |
Заблокирован |
|
20.01.2020, 04:55 |
4 |
while (i <= N && pA < (A / 2)); и раньше так было-бы
0 |
2atlantis 0 / 0 / 0 Регистрация: 09.01.2020 Сообщений: 67 |
||||
20.01.2020, 04:58 [ТС] |
5 |
|||
и раньше так было-бы
Вроде исправил) Большое спасибо
0 |
Заблокирован |
|
20.01.2020, 05:10 |
6 |
for (pA = AB-(B-p) а по буквам рассказать?
0 |
0 / 0 / 0 Регистрация: 09.01.2020 Сообщений: 67 |
|
20.01.2020, 05:56 [ТС] |
7 |
а по буквам рассказать? Не понимаю
0 |
Заблокирован |
||||
20.01.2020, 06:16 |
8 |
|||
0 |
Заблокирован |
|
21.01.2020, 13:39 |
9 |
OFF:дожили до компов где можно посчитать 264 зерен, осталось найти такую страну
0 |
Yetty 7427 / 5021 / 2891 Регистрация: 18.12.2017 Сообщений: 15,694 |
||||
21.01.2020, 16:04 |
10 |
|||
Сообщение было отмечено 2atlantis как решение РешениеHoliday13, если количество циклов заранее не известно, советовать менять цикл while на for не логично
цикл почему то не работает уберите точку с запятой подправил:
1 |
Заблокирован |
|
21.01.2020, 22:27 |
11 |
Yetty, я использовал for
0 |
Что делает цикл for
?
Он итерируется по объекту и присваивает значения элементов в переменную:
for i in 1, 2, 3, 4, 5:
print(i)
print(i)
Выведет:
1
2
3
4
5
5
Вы, видимо, подумали, что значение i = 0
, которые вы присвоили до цикла, останется и после него, но в вашем первом цикле вы изменяете значение i
на индексы строки, потому после цикла значение i == len(a) - 1
Ок, исправляем, переносим i
после цикла:
a = input()
col = 2
my_dict = {}
for i in range(len(a)):
my_dict[a[i]] = 1
i = 0
while i < len(a):
if a[i] * col in a:
my_dict[a[i]] += 1
col += 1
elif col > 2:
i += col
else:
col = 2
i += 1
for i in sorted(my_dict.items()):
print(i[0], i[1])
Проверяем приведённых значениях, вроде работает, а что если сделать не два, а три или более повторяющихся элементов .. не работает
Проверка того, что впереди есть такая последовательность
В строке a[i] * col in a
вы пытаетесь понять, существует ли последовательность символов такой длинны впереди, а проверяете, существует ли такая последовательность во всей строке:
Есил ввести "ataaa"
, то вот, что произойдёт:
(мы уже инициализиировали dict
и в нём уже лежит {"a": 1, "t": 1}
)
if a[i] * col in a:
, проверяем
i == 0
a[i] == "a"
col == 2
a[i] * col == "aa"
следовательно "aa" in a == True
, потому, что в a
есть "aa"
, хоть не в начале.
Ок, давайте исправим, используем срезы:
if a[i: i+col] == a[i] * col:
a[i: i+col]
— это срез с индекса i
до i+col
, не включая, пример:
если a == "abcdef", i == 3, col == 2
, то с той нашей строкой у нас будет a[i: i+col] == "de"
Ок, заменяем: if a[i] * col in a:
на if a[i: i+col] == a[i] * col:
(Проверяем, что все буквы в срезе — те, что нам нужны)
Смотрим, что если ввести "ataaapppp"
, опять не то считает …
Несколько длинных последовательностей
Логика таква, если есть последоательность такой длины, то мы задаём её, когда ма нашли конец последоательности, мы перезапускаем процесс, прасваивая col = 2
, и перескакиваем к концу последовательности, , если же мы не находили последовательности, то просто идём дальше, и вот проблема, вы перескакиваете не к концу, а на один символ дальше, а также перепутали места, где мы перезапусчкаем процесс, исправляем:
elif col > 2:
i += col - 1
col = 2
elif col == 2:
i += 1
Такс, проверяем, вроде работает, а есди использовать "ataaappppaaaaaaa"
, опять проблема, теперь с "a"
Несколько одинаковых последовательностей
Каждый раз, когды вы находите более длинную последовательность, вы добавляете к максимуму, и если длинных последовательностей несколько, то вы будете добавлять и добавлять, исправляем:
my_dict[a[i]] += 1
на
if my_dict[a[i]] < col:
my_dict[a[i]] = col
Результат
В итоге у нас получается что-то такое:
a = input()
col = 2
my_dict = {}
for i in range(len(a)):
my_dict[a[i]] = 1
i = 0
while i < len(a):
if a[i: i+col] == a[i] * col:
if my_dict[a[i]] < col:
my_dict[a[i]] = col
col += 1
elif col > 2:
i += col - 1
col = 2
elif col == 2:
i += 1
for i in sorted(my_dict.items()):
print(i[0], i[1])
Альтернативы
Это далеко не лучший или не самый просто способ рещить эту задачу, вот идейка, как бы реализовать это лучше:
Идти по строке, и запоминать, какой был последний символ, и как долго он повторяется:
string = input()
max_lengths = {}
sequence_length = 1
latest_symbol = None
for char in string:
if latest_symbol != char:
sequence_length = 1
if max_lengths.get(char, 0) < sequence_length:
max_lengths[char] = sequence_length
sequence_length += 1
latest_symbol = char
for i in sorted(max_lengths.items()):
print(*i)