Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
1 / 1 / 1
Регистрация: 16.11.2012
Сообщений: 27

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

22.12.2012, 04:43. Показов 1400. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
пишу лабу одногруппнице. задание: определить двунаправленный циклический список. элементы типа char*
реализовать функции:
1. проверка на пустоту
2. сколько элементов с одинаковыми соседями?
3. существует ли элемент равный следующему?
4. переставить элементы в обратном порядке между первым и последним вхождениями
5. вывод в файл.

для себя добавил функцию create и add
ООП не проходили. задание вообще странновато, мы прошли STL, мы не прошли язык Си, то есть никто не знает про strcmp() printf/scanf и т.д. ну это такое. всем известно что 70% времени находимся в универе и 70% инфы находим сами. неважно

на одном дыхании написал я вот такой вот говнокод:
list.h: (не парился с ifdef ifndef так как опять же раздельную компиляцию нам объяснили абыкак, а подруга объяснить не сможет)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
struct Elem 
{
    Elem *prev, *next;
    char *data;
};
 
typedef Elem* List;
 
List create(); //создать список
void add(List l, char* _data); //добавить елем
 
bool is_empty(List l); //пустой?
int  how_many_with_equal_neighbours(List l); //сколько эл-тов с одинаковыми соседями?
bool equal_to_next_exists(List l); //существует ли элемент равный следующему?
void inverse_between(List l, char* el); //переставить в обратном порядке между первым и последним вхождениями
void write(List l, std::ostream& out=std::cout); //написать в поток (cout по умолчанию, но можно использовать файловые потоки)
code.cpp (реализация)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "list.h"
 
 
List create() //создать список
{
    List l=new Elem; //выделяем память для списка
    l->data=""; //делаем пустую строку
    l->next=0; //указатель на следующий нулевой
    l->prev=0; //указатель на предыдущий - нулевой
    return l;
    /*сформировали заглавное звено списка*/
}
 
void add(List l, char* _data) //добавить елем
{
    if (!l->next) //если список пуст
        l->next->next=l->next->prev=l->next=new Elem; //создаем элемент и сразу зацикливаем его сам на себя (присваивание справа на лево)
    else
    {
        Elem* old_tail=l->next->prev; //сохраняем старый
        l->next->prev=l->next->prev->next=new Elem; //выделяем память (это будет новый хвост),хвост привязываем к последнему элементу, а потом к первому
        old_tail->next->prev=old_tail; //привязываем старый хвост к новому
        l->next->prev->next=l; //привязываем голову к хвосту
    }
    l->next->prev->data=_data; //заполняем хвост (выполняется в любом случае)
}
 
bool is_empty(List l) //пустой?
{
    return !l->next; //ну тут ясно. если указатель на следующий нулевой, вернем правду иначе ложь
}
 
int  how_many_with_equal_neighbours(List l) //сколько эл-тов с одинаковыми соседями?
{
    if (!l->next) return 0;
    Elem* tail=l->next->prev;//сохранили хвост
    int i=0;
    while ((l!=tail) && ( (l=l->next) || (i+=(strcmp(l->next->data, l->prev->data)?0:1)) ) );
    /* эквивалентно:
    while (l!=tail) 
    {
        if (!strcmp(l->next->data, l->prev->data) i++;
        l=l->next;
    }*/
    return i;
}
 
bool equal_to_next_exists(List l) //существует ли элемент равный следующему?
{
    if (!l->next) return false;
    Elem* tail=l->next->prev;
    while ((l=l->next) && strcmp(l->data,l->next->data) && l!=tail);
    /*эквивалентно:
    while (l!=tail)
    {
        l=l->next;
        if (!strcmp(l->data,l->next->data)) break;
    }*/
    return l!=tail || strcmp(l->data,l->next->data); //если не дошли до конца, или же если дошли, но последний равен первому
}
 
void inverse_between(List l, char* el) //переставить в обратном порядке между первым и последним вхождениями
{
    if (l->next==l->next->prev) return; //если список зациклен сам на себе, то там один элемент. если список пуст то оба указателя равны нулю
    Elem *first=0, *last=0, *tail=l->next->prev;
    while (l!=tail) 
    //нахождение первого и последнего вхождения:
    {
        l=l->next; //переходим к след. элементу
        if (!strcmp(l->data,el)) //если нашли строку
            if (!first) first=l; //если первое вхождение не найдено, то первое вхождение = этому звену
            else last=l; //иначе последнее вхождение = этому звену
    }
    if (!last) return; //если нету последнего вхождения, то елемент встречается один раз, так что выходим
    char* temp;
    while (first!=last && first->next!=last) //1е условие - если у нас нечетное кол-во эл-тов между first и last, 2е условие - если четное.
    {
        //передвигаем указатели навстречу друг другу
        first=first->next;
        last=last->prev;
        //меняем элементы местами
        temp=first->data;
        first->data=last->data;
        last->data=temp;
    }
}
 
void write(List l, std::ostream& out) //написать в поток (cout по умолчанию, но можно использовать файловые потоки)
{
    Elem* tail=l->next->prev;
    while (l!=tail) 
    {
        l=l->next;
        out<<l->data<<'\n';
    }
}
ну и наконец: main.cpp тестовая программа

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 "list.h"
 
void main()
{
    printf("Fill the list with 10 elements:\n");
    List list=create();
    add(list,"mm");
    for (int i=1; i<=10; i++)
    {
        char* el=new char[255]; 
        //если объявим снаружи цикла, адрес строки будет всегда один и тот же, и все элементы списка будут одинаковыми
        scanf("%s",el); //читаем с консоли 
        add(list,el); //добавляем в список
    }
    printf("\nYour list:\n");
    write(list); //выводим список в консоль
    if (!is_empty(list)) 
    {
        printf("Count of elements with equal neighbours: %d\n", how_many_with_equal_neighbours(list));
        printf("Element that equals to his right neighbour "+(equal_to_next_exists(list))?"exists":"does not exist\n");
        printf("Input string: ");
        char* str=new char[255];
        scanf("%s",str);
        inverse_between(list,str);
        printf("\n\nIf at least two \"%s\" are in list, the elements between first and last \"%s\" will be inverted",str,str);
        write(list);
    }
    else printf("The list is empty");
    system("pause");
}
теперь суть проблем:
проблем всего три: две мелкие и одна - вообще огонь
мелкая: некорректно работает how_many_with_equal_neighbours(list)
я как нормальный белый человек поставил точку останова, и давай f10 жать.
и тут меня начал есть факт, что нету автоматической слежки за переменными (как ее добавить - первая мелкая проблема)
некоторые переменные вообще нельзя отследить: в функции main не могу проследить за list, в функции how_many_with_equal_neighbours(list) не могу проследить за счетчиком i (вторая мелка проблема)

ну я себе и думаю: чтото не так с add(). давайте ка глянем в add
остановил отладку, поставил останов в add() и компилятор в него не зашел. я поставил останов перед вызовом add, жму f11. та же фигня, пропускает. а потом вижу, всплывает хинт: что-то по типу не могу зайти в функцию, так как я оптимизировал её и кода как такового нету, используйте директиву нескажу какую.
в общем это и есть та огонь-проблема. как мне отдебажить эту функцию, как убрать или поставить директиву, чтобы этот компилятор не оптимизировал мой восхитительнейший код?

я со своим кодом разобраться вполне могу, хотя советы не помешают, но все же главное - как решить те три проблемы которые я описал?

и да, если не лень, гляньте вообще весь код, не только проблемные функции. как можно его еще сократить (я только начал страдать этой фигней, собственно почему я люблю Си - за короткие и непонятные конструкции которые можно объяснять преподам и выглядеть умным)

Заранее спасибо

Добавлено через 6 минут
блин, перечитываю код, уже вижу ошибку в add()
code.cpp строка 23
вместо
l->next->prev->next=l; //привязываем голову к хвосту
надо
l->next->prev->next=l->next; //привязываем голову к хвосту

Добавлено через 19 минут
и еще одна ошибка, строка 59
вместо
return l!=tail || strcmp(l->data,l->next->data);
надо
return l!=tail || !strcmp(l->data,l->next->data);

все время забываю что strcmp() действует наоборот

Добавлено через 32 минуты
в общем я сделал эту функцию так: чуть чуть удлинил. видимо что-то неверно сократил, интересно что. и как убрать эту оптимизацию, на всякий случай расскажите все же. и переменные как наблюдать

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int  how_many_with_equal_neighbours(List l) //сколько эл-тов с одинаковыми соседями?
{
    if (!l->next) return 0;
    Elem* tail=l->next->prev;//сохранили хвост
    int i=0;
    do l=l->next; while ((l!=tail) && ( /*(l=l->next) ||*/ (i+=(strcmp(l->next->data, l->prev->data)?0:1)) ) );
    //эквивалентно:
    /*while (l!=tail) 
    {
        l=l->next;
        if (!strcmp(l->next->data, l->prev->data)) i++;
    }*/
    return i;
}
Добавлено через 1 минуту
как я выяснил в строке 6 никак не хотела выполняться l=l->next
удалось проследить за переменной l , но вот же зараза, цикл выполнялся ровно столько раз сколько в списке элементов. ужас какой-то, это я дурак или компилятор?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.12.2012, 04:43
Ответы с готовыми решениями:

отладить мой код, пожалуйста
Сама задача: (+ на картинке) Разработать алгоритм и записать программу вычисления значения функции с заданным шагом на указанных...

На мой взгляд круто оптимизировал сайт
Было 15-20 чел в день. А сейчас планирую взлететь после на мой взгляд хитрой оптимизации. Сайт про храмовую архитектуру Беларуси. У меня...

Я полностью оптимизировал код
Я полностью оптимизировал код по w3.org - что это даёт?

9
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
22.12.2012, 10:31
Цитата Сообщение от bychevoz Посмотреть сообщение
что нету автоматической слежки за переменными
в какой среде разработке работаете? я подозреваю что Visual Studio, я в ней не работаю но мне кажется что у майкрософта хватало ума чтоб гдето поместить окошко с локальными переменными, если не в ней, или не хватило( что сомнительно) есть такая штука называется watch, надо полазить на панели инструментов и где-то найтиЮ либо addwatch либо watchlist
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
22.12.2012, 10:59
Цитата Сообщение от Nixy Посмотреть сообщение
в какой среде разработке работаете? я подозреваю что Visual Studio, я в ней не работаю но мне кажется что у майкрософта хватало ума чтоб гдето
дак у у неё ума то хватает
не хватает у пользователей, которые пытаются в Relise отлаживать (а там уже оптимизатор все перекрутил) вместо Debug

Добавлено через 1 минуту
Цитата Сообщение от bychevoz Посмотреть сообщение
do l=l->next; while ((l!=tail) && ( /*(l=l->next) ||*/ (i+=(strcmp(l->next->data, l->prev->data)?0:1)) ) );
* * //эквивалентно:
сам себе злобный буратино
интересно что можно отладить в такой строчке
0
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
22.12.2012, 11:14
C++
1
2
3
4
5
do {
     l=l->next;
     i+=(strcmp(l->next->data , l->prev->data)?0:1);
    }
    while ((l!=tail));
с такой конструкцией все работает, единственое хочу уточнить, голова не должна быть к хвосту привязана быть?
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
22.12.2012, 11:48
Цитата Сообщение от Nixy Посмотреть сообщение
с такой конструкцией все работает,
так работать то работает
а если нет? как отлаживать?
чему равна l->next->data l->prev->data
что вернет strcmp ?
для отладки лучше разбить на три строчки и ввести временные переменные
0
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
22.12.2012, 12:15
не ну для отладки то да каждое действие по полкам, но потом то собрать надо, проблема то не в отладке была вроде как), а в том что внутри условия оператор
C++
1
i+=(strcmp(l->next->data , l->prev->data)?0:1);
не работал

Добавлено через 2 минуты
о увидел про голову и хвост
l->next->prev->next=l->next; //привязываем голову к хвосту
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.12.2012, 16:26
Цитата Сообщение от bychevoz Посмотреть сообщение
list.h: (не парился с ifdef ifndef так как опять же раздельную компиляцию нам объяснили абыкак, а подруга объяснить не сможет)
Лучше использовать assert - ты, ну или накрайняк самописные ф-ции, но и с макросами ничего сложного нет.

Ну это для отладки, а вообще обычно еще исключения возбуждают при ошибках

Добавлено через 5 минут
Цитата Сообщение от bychevoz Посмотреть сообщение
C++
1
2
3
4
bool is_empty(List l) //пустой? 
{ 
  return !l->next; //ну тут ясно. если указатель на следующий нулевой, вернем правду иначе ложь
}
Равноценно

C++
1
2
3
4
bool is_empty(List l) //пустой? 
{ 
  return (l->next == NULL);
}
Добавлено через 36 минут
Цитата Сообщение от bychevoz Посмотреть сообщение
list.h: (не парился с ifdef ifndef так как опять же раздельную компиляцию нам объяснили абыкак, а подруга объяснить не сможет)
М.. прдон не понял я наверное суть вопроса ... наверное речь про "стражи включения",
а не про отладку http://ru.wikipedia.org/wiki/Include_guard
0
1 / 1 / 1
Регистрация: 16.11.2012
Сообщений: 27
23.12.2012, 02:37  [ТС]
Цитата Сообщение от bychevoz Посмотреть сообщение
как я выяснил в строке 6 никак не хотела выполняться l=l->next
удалось проследить за переменной l , но вот же зараза, цикл выполнялся ровно столько раз сколько в списке элементов. ужас какой-то, это я дурак или компилятор?
Цитата Сообщение от bychevoz Посмотреть сообщение
некоторые переменные вообще нельзя отследить: в функции main не могу проследить за list, в функции how_many_with_equal_neighbours(list) не могу проследить за счетчиком i (вторая мелка проблема)
а с этим как быть?

и я знаю что такое watch можете просто подсказать в какой менюшке сделать его автоматическим
0
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
23.12.2012, 10:25
ну погуглите что такое watch я не знаю где вы работаете, в какой среде,и поэтому врятли смогу подсказать, а по сути программы она работает если заменить тем что мы написали вашу конструкцию, все делает
0
1 / 1 / 1
Регистрация: 16.11.2012
Сообщений: 27
24.12.2012, 07:45  [ТС]
да , я понял что основная проблема что я пытался отлаживать release))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.12.2012, 07:45
Помогаю со студенческими работами здесь

не могу понять почему не работает мой код
#include&lt;iostream&gt; #include&quot;cstring&quot; using namespace std; struct Spisok { char nameProduct; char count; char price; ...

Пожалуйста, исправьте мой код(если его можно так назвать)! Задача по Фотрану
Дана квадратная матрица размера n, получить матрицу того же порядка, в которой элемент равен 1, если соответствующий ему элемент исходной...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru