Модератор
Эксперт С++
 Аватар для zss
13728 / 10924 / 6482
Регистрация: 18.12.2011
Сообщений: 29,160
1

Распространенные ошибки

21.09.2014, 17:33. Показов 399357. Ответов 73
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Скачать pdf:
Часто встречающиеся Ошибки.pdf
Оглавление

Ошибки этапа компиляции
Программа не компилируется или компилируется с предупреждениями.
  1. Попытка модифицировать константу через указатель
  2. Неправильное понятие приведения
  3. Лишняя точка с запятой
  4. Отсутствие точки с запятой после определения классового типа
  5. Отсутствие возврата значения из функции
  6. Использование комментариев в #define
  7. Компилятор не находит iostream.h
  8. Внутри switch ошибка Case bypasses initialization of a local variable
  9. Передача двумерных массивов и указателей в функцию
  10. Не удается открыть файл stdafx.h
  11. Ошибка "unresolved external symbol _WinMain@16"
  12. Ошибка "This function or variable may be unsafe"
  13. Компилятор не находит шаблонов описанных в других файлах проекта
Ошибки этапа выполнения
Программа прекращает работу с сообщением об ошибке
  1. Выделение памяти без дальнейшего освобождения или неверное освобождение
  2. Возврат ссылки/указателя на локальную переменную
  3. Использование неинициализированной переменной
  4. Выход за пределы массива
  5. Ошибки при использовании функции scanf()
  6. Работа с локальной копией объекта, вместо работы с самим объектом
  7. Интерпретация одиночного char символа как символьной строки
  8. Ошибка преобразования: type ** в const type **
Неправильное поведение программы на этапе исполнения
Программа исполняется, но не так, как хотелось.
  1. Неожиданное закрытие окна
  2. "Неожиданное" целочисленное деление в арифметических выражениях
  3. Ошибки в логических выражениях
  4. Лишняя точка с запятой
  5. switch без break
  6. Сравнение вещественных чисел при вычислениях
  7. Сравнение char массивов
  8. Использование чисел, записанных в других системах счисления
  9. Проверки на принадлежность значения определенному интервалу
  10. Неверный аргумент тригонометрических функций
  11. Сравнение знаковой переменной с беззнаковой
  12. Использование запятой для отделения дробной части
  13. Забытое выделение тела цикла for, while и операторов if else
  14. Определение размера массива, переданного в качестве аргумента функции
  15. Порядок вычисления аргументов при вызове функции
  16. Некорректное использование логических переменных
  17. Локальная переменная экранирует переменную с таким же именем из вышестоящей области видимости
  18. Неправильное использование memset
  19. Ошибка при использовании счётчика цикла вне цикла
Алгоритмические ошибки
Ошибки, допущенные при разработке алгоритма
  1. Двойная перестановка строк или элементов массива
  2. Использование символа цифры вместо числа
Ошибки ввода-вывода
  1. Оставление символа '\n' в потоке ввода
  2. Ошибки при использовании функции scanf()
  3. При работе с fgetc чтение файла обрывается при достижении буквы 'я'
  4. При считывании из файла последний элемент читается дважды
  5. Запись сложных объектов в бинарный файл
Ошибки, связанные с отклонением от стандарта языка
  1. Неверный тип функции main()

Ошибки проектирования АТД (классов).
  1. Вызов виртуальной функции из конструктора
  2. Отсутствие точки с запятой после определения класса/структуры
  3. Неверный вызов конструктора базового класса из конструктора производного
  4. Неверный порядок при инициализации
  5. Нарушение правила ТРЕХ.
  6. Отсутствие виртуального деструктора в базовом классе
  7. Неправильное обращение к конструктору по умолчанию
  8. Не очевидные моменты с вызовом конструктора базового класса
  9. Неявно объявленный конструктор по умолчанию
  10. Перегрузка оператора >>
  11. Невозможно обратиться к protected члену, объявленному в базовом классе
Ошибки при использовании STL контейнеров
  1. Невалидные ссылки/указатели, при перемещении объектов
  2. Ошибки связанные с итераторами (кэширование размера контейнера)
  3. Ошибки связанные с итераторами (удаление элементов по итератору в циклах)
  4. Ошибки связанные с итераторами (префикс-постфиксные инкременты при удалении элементов в цикле)
36
Лучшие ответы (1)
21.09.2014, 17:33
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.09.2014, 17:33
Ответы с готовыми решениями:

Вывести самые распространенные женские и мужские имена
Помогите решить задачу пожалуйста! Написать программу, которая формирует файл записей данной структуры Type Student=Record ...

Вывести самые распространенные мужские и женские имена
Имеется массив записей о студентах, каждая из которых включает поля: фамилия, имя, отчество, пол, возраст, курс. Разработать программу,...

Ошибки после компиляции на Visual Express 2012.Ошибки в теме
Добрый вечер ребят помогите пожалуйста.Программа написана на Visual Express 2012.Обясните что поменять чтобы зароботало. После компиляции...

73
Модератор
Эксперт по электронике
8956 / 6722 / 921
Регистрация: 14.02.2011
Сообщений: 23,722
07.01.2015, 21:26 41
Author24 — интернет-сервис помощи студентам
Некорректное использование логических переменных
часто встречаю такую вешь
C++
1
2
3
4
5
6
bool tmp;
// здесь что то делается с tmp
if ( tmp == true )
{
    ...
}
if ( tmp == true ) и есть тавтология (тождественно истинное высказывание, инвариантное относительно значений своих компонентов, по - русски повтор)
рассмотрим подробнее
if срабатывает если в скобках ИСТИНА (true) если ЛОЖЬ (false) то управление передается ветке else
теперь смотрим tmp==true tmp имеет значение true результат true, if исполняется
tmp==true tmp имеет значение false результат false, исполняется else
как видим результат равен tmp
поэтому достаточно, и необходимо написать if ( tmp ) вместо if ( tmp == true )
ошибка не так безобидна, как она кажется
в WinApi до сих пор используется тип BOOL это макрос int
и в разных версиях компилятора TRUE имело значение и 1 и -1 (все биты единицы)
а в языке C, C++ принято соглашение все что не 0 это ИСТИНА 0 это ЛОЖЬ
теперь представим себе что в переменную типа
BOOL tmp записали 1 это по соглашениям языка все равно что tmp=ИСТИНА
но TRUE определен как -1
и условие if ( tmp == TRUE ) не сработает
тогда как if ( tmp ) сработает правильно
в старых MSDNах писали, не знаю как сейчас, нельзя сравнивать с TRUE
только с FALSE (поскольку оно однозначно 0)
т.е наша запись должна выглядеть так
C++
1
if ( tmp != FALSE )
или так
C++
1
if ( tmp )
1
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5046 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
09.01.2015, 00:17 42
Цитата Сообщение от ValeryS Посмотреть сообщение
36. Некорректное использование логических переменных
Таки распространенная ошибка? Не видел чтобы множество новичков использовали BOOL из WinAPI. И тем более сравнивали так:
C++
1
if ( tmp == TRUE )
И заявленная вами же фраза
Цитата Сообщение от ValeryS Посмотреть сообщение
ошибка не так безобидна, как она кажется
никак не относится к выражению
Цитата Сообщение от ValeryS Посмотреть сообщение
if ( tmp == true )
Условие выше никогда не является ошибочным. Избыточным да, но не ошибочным.
2
Эксперт С++
 Аватар для hoggy
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
10.01.2015, 01:49 43
Невалидные ссылки/указатели, при перемещении объектов.

Пример: Реаллок вектора:

История болезни:

1. В вектор напихиваются объекты по значению.
2. Из вектора срисовывается ссылка/указатель на какое либо из его значений.
3. В вектор напихивают ещё некоторое количество объектов.
4. В какой то момент резерв памяти иссякает, и вектор реалочится - расширяет буфер, переносит туда свои объекты. В результате объекты меняют адрес.

5. Выданные наружу ссылки/указатели становятся недействительными, но никто никого об этом не предупредил.
6. Обращение по невалидному указателю/ссылки - крэш времени выполнения.

Искать причину таких вылетов затруднительно, потому что:
1. Авария обычно происходит далеко от места причины аварии.

2. В целях оптимизации, для вектора любят резервировать память (vector::reserve).
В результате в большинстве случаев резерва хватает, и вектор редко реалочится.
В результате баги долгое время могут оставаться незамеченными,
а когда стреляет - довольно сложно сказать почему (сп пункт 1)

Пример:
http://rextester.com/AWJSK45012

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Title of this code
// g++  4.8.2
 
#include <iostream>
#include <vector>
 
struct isome
{
    virtual ~isome() {}
    virtual void foo() = 0;
};
 
struct some : isome
{
    int val = 10;
 
    virtual void foo() {
        val += 10; std::cout << "val = " << val << '\n';
    }
};
 
int main()
{
    std::cout << "Hello, world!\n";
 
    std::vector <some> vec;
 
    vec.emplace_back();
 
    some & s = vec.back();
    s.foo();
 
    vec.push_back( some() );
    vec.push_back( some() );
    vec.push_back( some() );
    vec.push_back( some() );
    vec.push_back( some() );
    vec.push_back( some() );
    vec.push_back( some() );
    vec.push_back( some() );
 
    s.foo();
}
Подобную ошибку можно выделить в целый класс ошибок связанных с "неперемещаемостью объектов".
Потому что помимо вектора, она может встречаться в самых разных ситуациях.

Например: создали std::function на метод класса, объект переехал, делегат покрэшел весь процесс.
И тп.
5
Модератор
Эксперт С++
 Аватар для zss
13728 / 10924 / 6482
Регистрация: 18.12.2011
Сообщений: 29,160
19.01.2015, 10:19  [ТС] 44
Неправильное обращение к конструктору по умолчанию.
C++
1
2
3
4
5
6
7
8
9
10
class A
{
public:
    A() {}
    ...
};
 
...
 
A a();
Объявляется переменная a типа A.
Круглые скобки ставятся для явного указания, что нужен конструктор без параметров.

Однако, такая конструкция интерпретируется как объявление (прототип) функции без параметров
с именем a, которая возвращает значение типа A.
Правильным будет такое объявление:
C++
1
A a;
5
Эксперт С++
 Аватар для hoggy
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.01.2015, 19:04 45
Не очевидные моменты с вызовом конструктора базового класса
Ошибка на внимательность:
При копировании объектов вместо конструктора копии,
у базового класса запускается конструктор по умолчанию


Рассмотрим код:
http://rextester.com/CLL66454
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Title of this code
// g++  4.8.2
 
#include <iostream>
 
struct base
{
    ~base() { delete [] mData; }
    base()
        : mSize( 0 )
        , mData( nullptr )
    {}
 
    base( const size_t size )
        : mSize( size )
        , mData( new int[size] )
    {}
 
    base( const base & rhs )    // <--- раз мы его объявили, значит нам это важно
        : mSize( rhs.mSize )    //  он обязательно должен запуститься при копировании объектов
        , mData( new int [mSize] )
    {}
 
    size_t  mSize;
    int *   mData;
};
 
struct der : base
{
    der()   // <---- какой конструктор base будет запущен?
        : mValue( 0 )
    {}
 
    der( const size_t size, const int value = 0 )
        : base( size )
        , mValue( value )
    {}
 
    der( const der & rhs )  // <---- какой конструктор base будет запущен?
        : mValue( rhs.mValue )
    {}
 
    void view() const
    {
        std::cout << "value = " << mValue
            << " : size = " << mSize <<'\n';
    }
 
    int mValue;
};
 
int main()
{
    std::cout << "Hello, world!\n";
 
    der d1( 10, 10 );
    d1.view(); // value = 10 : size = 10
 
    der d2 = d1;
    d2.view(); // что будет выведено?
}
Правильный ответ:

Кликните здесь для просмотра всего текста

Не по теме:

value = 10 : size = 0



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

Оно и понятно: ведь именно такое поведение подсказывает здравый смысл.

Однако на самом деле все иначе:
программист должен явно указать какой базовый конструктор нужно запустить:
C++
1
2
3
    der( const der & rhs ) // <---- какой конструктор base будет запущен?
        : mValue( rhs.mValue ), base( rhs )
    {}
По умолчанию компилятор запускает только и только "конструкторы по умолчанию".
7
Эксперт С++
 Аватар для hoggy
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.03.2015, 17:47 46
Ошибки связанные с итераторами (кэширование размера контейнера).

Такие ошибки обычно проявляются собственно по прямому назначению итераторов:
в пробегах по циклам.

Рассмотрим примеры:
C++
1
for ( auto i = vec.begin(); i != vec.end(); ++i ) { ... }
C++
1
2
const auto e = vec.end();
for ( auto i = vec.begin(); i != e; ++i ) { ... }
Какой способ работает быстрее?

На самом деле - 2й способ, потому что в первом случае на каждом шаге цикла
каждый раз заново рассчитывается размер контейнера.

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

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

Ну так вот это - не правда. И ниже я объясню почему.

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

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

В худшем случае это приведет к некорректному поведению программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>
 
using namespace std;
 
int main()
{
    vector <int> vec( 2, 2 ); 
 
    auto e = vec.end(); // <--- закэшировали конечное значение
 
    // --- мы хотим бежать по всему контейнеру
    for ( auto it = vec.begin(); it != e; ++it )
        if ( *it == 2 )
            vec.insert( it, 3 ); // <--- сколько раз будет осуществлена вставка?
 
    for ( auto i : vec )
        std::cout << i << ", ";
    std::cout << '\n';
}
В лучшем, получаем крэш:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>
 
using namespace std;
 
int main()
{
    vector <int> vec( 5, 5 );
 
    auto e = vec.end(); // <--- закэшировали конечное значение
 
    // --- мы хотим бежать по всему контейнеру
    for ( auto it = vec.begin(); it != e; ++it )
        if ( *it == 5 )
            vec.erase( it ); 
}
В общем случае, компилятор может оптимизировать только константы в условии цикла.
Но он не оптимизирует мутабельную переменную,
именно потому, что в теле цикла эти переменные могут быть изменены.

В лучшем случае компилятор может оптимизировать и мутабельную переменную,
при условии, что в теле цикла ему доступна вся полнота информации,
и он может гарантировать, что её оптимизация не нарушит логику работы цикла.
3
Эксперт С++
 Аватар для hoggy
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.03.2015, 17:47 47
Ошибки связанные с итераторами (удаление элементов по итератору в циклах).

Рассмотрим пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <list>
 
using namespace std;
 
int main()
{
    list <int> mylist; 
 
    for ( size_t n = 0; n < 5; ++n )
        for( size_t i = 0; i < 3; ++i )
            mylist.emplace_back( n );
 
    // --- мы хотим бежать по всему контейнеру
    // --- и удалить все элементы со значением 3
    for ( auto it = mylist.begin(); it != mylist.end(); ++it )
        if ( *it == 3 )
            mylist.erase( it ); // <--- итератор стал невалидным
}
Получаем крэш.
После удаления элемента, итератор ссылается на несуществующий элемент.
Он не знает о том, что он теперь уже - невалидный.
Нельзя использовать невалидные итераторы.
Однако в цикле для него делается ++it.

Первая мысль, которая может придти в голову новичку:
после удаления, присвоить итератору новое значение, что бы итератор всегда оставался валидным:
C++
1
it = mylist.erase( it );
И тогда он совершает другую весьма распространенную ошибку:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <list>
 
using namespace std;
 
int main()
{
    list <int> mylist; 
 
    for ( size_t n = 0; n < 5; ++n )
        mylist.emplace_back( n ),
        mylist.emplace_back( n ),
        mylist.emplace_back( n );
 
    cout << "mylist = { ";
    for ( const auto & i : mylist )
        cout << i << ", ";
    cout << "}\n";
 
    // --- мы хотим бежать по всему контейнеру
    // --- и удалить все элементы с ключем 3
    for ( auto it = mylist.begin(); it != mylist.end(); ++it )
        if ( *it == 3 )
            it = mylist.erase( it );
 
    cout << "mylist = { ";
    for ( const auto & i : mylist )
        cout << i << ", ";
    cout << "}\n";
}
Крушений больше не происходит, но логика работы нарушена - алгоритм "проскочил" мимо одного из удаляемых элементов.

Это связанно с тем, что инструкция: it = mylist.erase( it );
Присваивает итератору ссылку на элемент, идущий сразу же следом после удаляемого.
После чего отрабатывает инструкция цикла ++it
И получается, что алгоритм перескакивает через элемент.

Правильная версия выглядит так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <list>
 
using namespace std;
 
int main()
{
    list <int> mylist;
 
    for ( size_t n = 0; n < 5; ++n )
        mylist.emplace_back( n ),
        mylist.emplace_back( n ),
        mylist.emplace_back( n );
 
    cout << "mylist = { ";
    for ( const auto & i : mylist )
        cout << i << ", ";
    cout << "}\n";
 
    // --- мы хотим бежать по всему контейнеру
    // --- и удалить все элементы с ключем 3
    // --- цикл больше не инкрементирует счетчик
    for ( auto it = mylist.begin(); it != mylist.end(); )
        if ( *it == 3 )
            it = mylist.erase( it );
        else
            ++it; // <--- мы делаем это вручную
 
    cout << "mylist = { ";
    for ( const auto & i : mylist )
        cout << i << ", ";
    cout << "}\n";
}
3
Эксперт С++
 Аватар для hoggy
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.03.2015, 17:47 48
Ошибки связанные с итераторами (префикс-постфиксные инкременты при удалении элементов в цикле).

Многие новички следуют за опытными специалистами, подражая их стилю.

А в профессиональном коде часто можно встретить
использование свойств префикс-постфикс операций:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <list>
 
using namespace std;
 
int main()
{
    list <int> mylist; 
 
    for ( size_t n = 0; n < 5; ++n )
        mylist.emplace_back( n ),
        mylist.emplace_back( n ),
        mylist.emplace_back( n );
 
    cout << "mylist = { ";
    for ( const auto & i : mylist )
        cout << i << ", ";
    cout << "}\n";
 
    // --- мы хотим бежать по всему контейнеру
    // --- и удалить все элементы с ключем 3
    for ( auto it = mylist.begin(); it != mylist.end(); )
        if ( *it == 3 )
            mylist.erase( it++ ); // <--- постфикс
        else
            ++it;
 
    cout << "mylist = { ";
    for ( const auto & i : mylist )
        cout << i << ", ";
    cout << "}\n";
}
Если нечаянно перепутать его с префиксной формой, получим крэш.

Это уже особенности инкрементов.
И больше относится к ошибкам связанным именно с инкрементами, нежели с итераторами.

При постфиксонй форме будет удален текущий элемент,
несмотря на то, что сам итератор инкременируется ещё до удаления.

А при префиксной - сначала инкрементируется,
и только потом будет удален уже следующий элемент,
что само по себе уже ошибка в логике.

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


Несмотря на то, что ошибки связанные с итераторами,
и ошибки связанные с префикс-постфикс инкрементом - это немножно разные плоскости,
тем не менее они чаще всего встречаются рядышком в циклах,
при пробеге по контейнеру.

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

Часто джуниоры находят только одну ошибку.

Резюмируя:

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

2. Не нужно спорить, что быстрее: ++i или i++
Нужно понимать, что делают обе формы инкремента, и использовать их по назначению.
3
Модератор
Эксперт по электронике
8956 / 6722 / 921
Регистрация: 14.02.2011
Сообщений: 23,722
21.04.2015, 07:53 49
Неявно объявленный конструктор по умолчанию

Вот еще заметил такую вещь (это скорее ошибка терминологии и непонимание работы компилятора ):
C++
1
Matrix(); // конструктор по умолчанию
взято отсюда
Компилятор не понимает тип Array

в данном случае это не конструктор по умолчанию а конструктор без параметров
конструктор по умолчанию это конструктор который вставляет компилятор,который чаще всего ничего не делает
как только мы описали хоть один конструктор конструктор по умолчанию пропадает
например
C++
1
2
3
4
5
class A 
{
}
 
A a;
здесь сработает конструктор по умолчанию
а вот здесь
C++
1
2
3
4
5
6
class A 
{
    A( int b );
}
 
A a;
получим ошибку компиляции, нет подходящего конструктора, поскольку конструктор по умолчанию пропал, а конструктора без параметров нет
необходимо описать конструктор без параметров
возможный выход описание конструктора с параметрами по умолчанию
C++
1
2
3
4
5
6
class A
{
    A( int b = 0 );
}
 
A a;
примерно то же относится и к конструкторам копирования и деструкторам, если мы их не описали, то компилятор вставит свои, не всегда они делают то что нужно.
0
 Аватар для Kastaneda
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
22.04.2015, 14:16 50
Цитата Сообщение от ValeryS Посмотреть сообщение
в данном случае это не конструктор по умолчанию а конструктор без параметров
конструктор по умолчанию это конструктор который вставляет компилятор,который чаще всего ничего не делает
как только мы описали хоть один конструктор конструктор по умолчанию пропадает
Из Стандарта (гл. 12.1)
A default constructor for a class X is a constructor of class X that can be called without an argument. If
there is no user-declared constructor for class X, a default constructor is implicitly declared.
Т.е. конструктор который может быть вызван без аргументов (важно - не конструктор без параметров, а может быть вызван без аргументов) и есть конструктор по умолчанию. Отсюда следует, что вот это
C++
1
A( int b = 0 );
тоже конструктор по умолчанию.
5
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
27.05.2015, 13:35 51
Некоторые замечания по уже размещенным ошибкам.
Цитата Сообщение от zss Посмотреть сообщение
C++
1
2
3
#include <iostream> 
... 
system( "pause" );
system() объявлена в <cstdlib>, а не в <iostream>
Цитата Сообщение от ValeryS Посмотреть сообщение
Если же выдается сообщение об ошибке, то нужно использовать операцию
reinterpret_cast<новый_тип>(выражение).
Далеко не факт. Пример:
C++
1
int i{ 100.500 };
Получим ошибку (не предупреждение):
error: type 'double' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
Но устраняется она, тем не менее, static_cast'ом:
C++
1
int i{ static_cast<int>( 100.500 ) };
Цитата Сообщение от zss Посмотреть сообщение
Использование присваивания (=) вместо сравнения (==).
C++
1
if ( a = 2 )
всегда истина
Тут надо уточнить, что a имеет стандартный тип (например int), а не пользовательский.
Иначе возможен и ложный результат.
Цитата Сообщение от MrGluck Посмотреть сообщение
освобождайте её с помощью оператора delete в конце программы
Правильнее было бы сказать "... когда память больше никому не нужна".

Цитата Сообщение от daslex Посмотреть сообщение
C++
1
if ( fabs( a - b ) < 1e-3 )
Хорошо бы заменить на std::abs (всё таки раздел плюсов тут)

Цитата Сообщение от KOPOJI Посмотреть сообщение
C++
1
if ( 0 <= x || x <= 10 )
...
Следовательно, условие всегда истинное.
Снова нужно уточнить тип и не только, иначе истина может оказаться ложью даже для стандартного типа double.

To be continued ...
2
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
24.06.2015, 20:40 52
По поводу этого:
Распространенные ошибки
C++
1
cin.ignore( cin.rdbuf()->in_avail() ); // пропустить все оставшиеся символы
В Linux и MinGW cin.rdbuf()->in_avail() не работает без предварительного ios_base::sync_with_stdio( 0 ).
C++
1
cin.sync();
В Linux не работает.
1
2836 / 1645 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
25.06.2015, 17:06 53
Должно работать везде и всегда:
C++
1
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
08.08.2015, 20:38 54
Ошибка преобразования: Type ** в const Type **.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
class A {
public:
    void modify() { /*...*/ } // метод, изменяющий состояние объекта
};
 
int main() {
    const A x;
    A * p;
    const A ** q = &p;  // q указывает на p; это ошибка (к счастью компилятор нас об этом предупредит)
    *q = &x;            // p указывает на x
    p->modify();        // проблема: изменение объекта const A через указатель на не константу p!
}
Еще одно объяснение ошибки: Const - обещание (гарантия) или требование?
0
14 / 14 / 6
Регистрация: 11.07.2015
Сообщений: 147
11.03.2016, 11:30 55
Опечатка в имени метки default в блоке switch.

Пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <cstdio>
using namespace std;
int num;
int main()
{
    setlocale(LC_ALL, "");
    cout << "Введите число: ";
    cin >> num;
    switch (num % 5)
    {
    case 0:
        cout << "Число делится на 5 без остатка." << endl;
        break;
    case 1:
        cout << "Число делится на 5 с остатком 1." << endl;
        break;
    case 2:
        cout << "Число делится на 5 с остатком 2." << endl;
        break;
    dafault:
        cout << "Число делится на 5 с остатком 3 или 4." << endl;
    }
    system("pause");
    return 0;
}
Данный код откомпилируется (по крайней мере в Visual Studio), но блок dafault никогда не будет выполнен.
1
Модератор
Эксперт С++
 Аватар для zss
13728 / 10924 / 6482
Регистрация: 18.12.2011
Сообщений: 29,160
11.03.2016, 12:28  [ТС] 56
anem, Оно откомпилируется с предупреждением:
warning C4102: dafault: неиспользованная метка
Значит, это еще один пример того, что изречение
"Ребята, читайте сообщения о предупреждениях!"
не голословное!
1
Модератор
Эксперт по электронике
8956 / 6722 / 921
Регистрация: 14.02.2011
Сообщений: 23,722
13.03.2016, 11:15 57
Цитата Сообщение от anem Посмотреть сообщение
Данный код откомпилируется
разумеется
потому что компилятор это считает меткой, с тем же успехом можно было написать bla_bla_bla:
но компилятор предупреждает
Цитата Сообщение от zss Посмотреть сообщение
warning C4102: dafault: неиспользованная метка
так что прав zss,
Цитата Сообщение от zss Посмотреть сообщение
"Ребята, читайте сообщения о предупреждениях!"
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
19.03.2016, 02:41 58
Данное сообщение относится скорее всего к:
Ошибки, связанные с отклонением от стандарта языка
Речь пойдет о файле (всеми любимом) windows.h
О его воинственном нраве можно много чего в сети разыскать. Я покажу это на примере простой задержки перед возвратом:
C++
1
2
3
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.clear();
cin.get();
если кто-то заметит, что лучше например:
C++
1
2
3
cin.ignore(cin.rdbuf()->in_avail());
cin.clear();
cin.get();
я не буду спорить, так как привожу данный код для примера. Итак:
C++
1
2
3
4
5
6
7
8
#include <iostream>
#include <windows.h>//для локали
#include <limits>
//--------
//--------
cin.ignore(numeric_limits<streamsize>::max(), '\n');//это не компилируется
cin.clear();
cin.get();
дело в том, что в файле windows.h есть макрос который перекрывает max следующим образом:
C++
1
#define max(a, b) (((a)>(b))?(a):(b))
я решил вопрос так:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <limits>
#include <windows.h>//для локали
 
#ifdef max(a, b) //без этого
#undef max(a, b) 
#endif //и этого одновременно можно обойтись 
//--------------------------
//--------------------------
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.clear();
cin.get();
локаль данное определение не использует, но хуже если в программе есть другие ms фрагменты котором нужен их max

Вполне возможно что иногда так можно обойти и другие конфликты связанные с этим файлом.
2
Неэпический
 Аватар для Croessmah
18124 / 10709 / 2063
Регистрация: 27.09.2012
Сообщений: 26,996
Записей в блоге: 1
19.03.2016, 07:02 59
IGPIGP, при
C++
1
ignore(numeric_limits<streamsize>::max(), '\n');
если в потоке не будет '\n', то безнадежно испортим поток.
При
C++
1
cin.ignore(cin.rdbuf()->in_avail());
in_avail может не вернуть то, что мы хотим.
Можно, конечно, поставить sync_with_stdio(false),
но это, если не ошибаюсь, тоже не даст никакой гарантии,
так что этот способ тоже не особо переносим.

Что касается get, то тоже не факт что сработает.
Недавно натыкался на то, что get удалял один символ из потока,
тогда как '\n' был из двух, так что пришлось делать get два раза, чтобы оно работало.
Следовательно, get тоже никакой гарантии не дает.

Как по мне, то лучше читать в строку и уже потом парсить.
ИМХО, это самое надежное решение.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
19.03.2016, 10:48 60
Цитата Сообщение от Croessmah Посмотреть сообщение
если в потоке не будет '\n', то безнадежно испортим поток.
Я же говорю, для примера написал. Если нет '\n' то должно очистить до конца ведь?
Цитата Сообщение от Croessmah Посмотреть сообщение
так что пришлось делать get два раза, чтобы оно работало.
Это древний и вполне звонкий бубен.
0
19.03.2016, 10:48
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.03.2016, 10:48
Помогаю со студенческими работами здесь

Распространенные ошибки
Оглавление Ошибки этапа компиляции (В процессе компиляции выдается либо сообщение об ошибке, либо предупреждение) - Попытка...

безопасность и распространенные ошибки
Тут наткнулся на очень интересные тексты: http://werad.narod.ru/articles/programm6.html http://werad.narod.ru/articles/programm9.html...

безопасность и распространенные ошибки
Тут наткнулся на очень интересные тексты: http://werad.narod.ru/articles/programm6.html http://werad.narod.ru/articles/programm9.html...

Распространенные ошибки SEO и ASP.NET 2.0
Здравствуйте, существуют несколько СЕО проблем при использовании ASP.NET, ниже я опишу эти проблемы, нужно найти простое и эффективное...

Самые распространенные строки
type Mytype = record name:string; surname:string; end; var Students:Mytype; MyFile:file of Mytype; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему

Редактор формул (кликните на картинку в правом углу, чтобы закрыть)
Опции темы

Новые блоги и статьи
Ключевые слова Python
hw_wired 15.02.2025
Ключевые слова в Python - это специальные зарезервированные слова, которые имеют особое значение и функции в языке. В настоящее время Python включает 35 ключевых слов и 4 мягких ключевых слова. Эти. . .
Отличия изменяемых и неизменяемых типов в Python
hw_wired 15.02.2025
В Python существует принципиальное различие между изменяемыми (mutable) и неизменяемыми (immutable) типами данных, которое оказывает существенное влияние на работу программ. Это различие часто. . .
Python: сравнение списков и кортежей
hw_wired 15.02.2025
В Python последовательности являются одними из самых важных и часто используемых типов данных. Они позволяют хранить упорядоченные наборы элементов, к которым можно обращаться по индексу. Среди всех. . .
Как скачивать файлы с URL с помощью Python
hw_wired 15.02.2025
Для скачивания файлов Python предлагает как встроенные средства, так и сторонние библиотеки. Встроенный модуль urllib из стандартной библиотеки обеспечивает базовую функциональность для работы с URL. . .
Использование SQLAlchemy в Python
hw_wired 15.02.2025
SQLAlchemy - мощная библиотека для работы с базами данных в Python, которая предоставляет полноценный набор средств для объектно-реляционного отображения (ORM) и обширные возможности для работы с. . .
Взаимодействие с REST API в Python
hw_wired 15.02.2025
В современном мире разработки программного обеспечения REST API стал неотъемлемой частью архитектуры веб-приложений. API (Application Programming Interface) - это набор правил и протоколов,. . .
Разделение строк в Python
hw_wired 15.02.2025
Python предлагает богатый набор возможностей для работы со строками, и среди них разделение строк занимает особое место. Этот процесс позволяет разбивать текст на отдельные компоненты, что критично. . .
Объединение строк в Python
hw_wired 15.02.2025
При работе с текстовыми данными в Python нередко возникает необходимость объединять несколько строк в одну. Это может потребоваться при форматировании вывода, обработке текстовых файлов или создании. . .
Лучшие игровые движки на Python
hw_wired 15.02.2025
В последнее время разработка игр стала одним из самых популярных направлений программирования, и Python не остался в стороне от этого тренда. Несмотря на то, что Python обычно не ассоциируется с. . .
Декоратор jit в Python
hw_wired 15.02.2025
Если вы достаточно долго изучаете программы и пакеты на Python для машинного обучения, то наверняка замечали, что паттерн "JIT-декоратор" довольно популярен. Этот подход позволяет превратить обычные. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru