2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней. На страницу 1, 2, 3, 4, 5 ... 7  След.
 
 Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 11:30 


16/10/14

667
Столкнулся с совершенно непонятным мне эффектом, работа оператора if else меняется из-за внесения двух казалось бы ни на что не влияющих переменных

На вход программ подаётся текстовый файл:

7
push 1
push 2
push 3
push 4
push 5
push 6
pop

Вывод осуществляется в консольное окно

По задумке если слово push то на выход должно выводиться число следующее за этим словом, а если pop то слово NO

Вот эта программа (с бесполезной переменной) работает правильно, выводя единственное NO

код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
int main() {
        freopen("input.txt", "r", stdin);
        char s[4];
        int Q, arr[20];
        scanf("%d", &Q);
        int j=0;                // объявление бесполезной переменной
        for(int i=0; i<Q; ++i) {
                scanf("%s", s);
                if(s[1]=='u') {
                        scanf("%d", &arr[i]);
                        printf("%d\n", arr[i]);
                        ++j; // изменение бесполезной переменной
                }                                              
                else {
                        printf("NO\n");
                }                                      
        }                      
        return 0;
}


Вывод такой:
1
2
3
4
5
6
NO

Вот эта программа (с бесполезной переменной в другом блоке) тоже работает правильно, выводя единственное NO

код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
int main() {
        freopen("input.txt", "r", stdin);
        char s[4];
        int Q, arr[20];
        scanf("%d", &Q);
        int j=0;  // объявление бесполезной переменной
        for(int i=0; i<Q; ++i) {
                scanf("%s", s);
                if(s[1]=='u') {
                        scanf("%d", &arr[i]);
                        printf("%d\n", arr[i]);        
                }                                              
                else {
                        printf("NO\n");
                        ++j; // изменение бесполезной переменной
                }                                      
        }                      
        return 0;
}


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

код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
int main() {
        freopen("input.txt", "r", stdin);
        char s[4];
        int Q, arr[20];
        scanf("%d", &Q);
        int j=0, k=0; // объявление двух бесполезных переменных
        for(int i=0; i<Q; ++i) {
                scanf("%s", s);
                if(s[1]=='u') {
                        scanf("%d", &arr[i]);
                        printf("%d\n", arr[i]);
                        ++j;    //изменение первой бесполезной переменной
                }                                              
                else {
                        printf("NO\n");
                        ++k; //изменение второй бесполезной переменной
                }                                      
        }                      
        return 0;
}


Вывод такой:
1
2
3
4
5
6
NO
NO
NO
NO
NO
NO

Каким образом эти две вместе взятые бесполезные переменные меняют работу оператора if else?

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 11:43 


27/08/16
5465
Для начала увеличьте длину буфера s до чего-нибудь более безопасного. Он у вас переполняется.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 11:50 


16/10/14

667
realeugene
Спасибо, проблема решена

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 12:17 
Заслуженный участник
Аватара пользователя


02/08/11
5647
Вот по причине таких проблем рекомендуется всегда передавать длину буфера явно. В частности, при использовании scanf вместо
Код:
char s[4];
scanf("%s", s);
лучше делать так:
Код:
char s[3 + 1];
scanf("%3s", s);
Тогда при любом содержимом входного файла переполнения не будет.

Обратите также внимание на запись 3 + 1 вместо просто 4: это снижает вероятность запутаться и забыть, что из четырёх байт только три можно задействовать для полезной информации.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 13:27 


27/08/16
5465

(Оффтоп)

warlock66613 в сообщении #1344128 писал(а):
Обратите также внимание на запись 3 + 1 вместо просто 4: это снижает вероятность запутаться и забыть, что из четырёх байт только три можно задействовать для полезной информации.
Это из категории советов для начинающих программистов. Человек с минимальным опытом программирования на С про то, что все строки в программе нуль-терминированные, уже не забывает.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 14:07 
Заслуженный участник
Аватара пользователя


02/08/11
5647

(Оффтоп)

realeugene в сообщении #1344138 писал(а):
Это из категории советов для начинающих программистов.
Нет, это совет для всех, в том числе для опытных программистов, которые знают, что вовсе не все строки (а тем более массивы байт) в программе нуль-терминированные.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 14:51 


27/08/16
5465

(Оффтоп)

warlock66613 в сообщении #1344143 писал(а):
Нет, это совет для всех, в том числе для опытных программистов, которые знают, что вовсе не все строки (а тем более массивы байт) в программе нуль-терминированные.
Простите, но по моим наблюдениям, опытные программисты в подобных советах не нуждаются и как правило плюют на подобные советы, вырабатывая собственный стиль (или принимая стиль проекта). Но вот если в сишной программе не нуль-терминированная строка передаётся куда-нибудь как const char* без длины, то за подобные чудеса нужно казнить немедленно.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 14:55 
Заслуженный участник
Аватара пользователя


02/08/11
5647

(Оффтоп)

realeugene в сообщении #1344151 писал(а):
опытные программисты в подобных советах не нуждаются
Ну, те которые этим советам не следуют - очевидно нуждаются.
realeugene в сообщении #1344151 писал(а):
и как правило плюют на подобные советы
Это никак не мешает давать для них такие советы.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 15:23 


27/08/16
5465

(Оффтоп)

warlock66613 в сообщении #1344154 писал(а):
Ну, те которые этим советам не следуют - очевидно нуждаются.

Простите, но мне подобное мнение не кажется мнением опытного практического разработчика. Не похоже. Стиль кодирования определяется осознанно и централизованно, а не так, как вам кажется.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 16:12 
Заслуженный участник
Аватара пользователя


02/08/11
5647

(Оффтоп)

realeugene в сообщении #1344162 писал(а):
Стиль кодирования определяется осознанно и централизованно, а не так, как вам кажется.
Простите, не смог расшифровать смысл этой фразы.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 16:22 


27/08/16
5465

(Оффтоп)

warlock66613 в сообщении #1344177 писал(а):
Простите, не смог расшифровать смысл этой фразы.
Это просто: существует такое понятие, как style guide, насаждаемый в крупных проектах централизованно. Именно в нём описывается, как нужно писать код в данном проекте. В чужой монастырь со своим уставом не ходят, но попав в монастырь устав приходится соблюдать.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 16:31 
Заслуженный участник
Аватара пользователя


02/08/11
5647

(Оффтоп)

realeugene в сообщении #1344178 писал(а):
существует такое понятие, как style guide, насаждаемый в крупных проектах централизованно. Именно в нём описывается, как нужно писать код в данном проекте. В чужой монастырь со своим уставом не ходят, но попав в монастырь устав приходится соблюдать.
Всё не так просто. Во-первых, в любом случае кто-то этот гид пишет - в таком случае совет как раз ему (им) и предназначается. Во-вторых, далеко не все мелочи регламентируются, и далеко не все из регламентированных реально соблюдаются. То есть многое остаётся на усмотрение разработчика. В третьих, styleguide - это не что-то незыблемое, и с течением времени такие вещи пересматриваются и меняются.

В данном случае, сложно даже просто представить как могло бы выглядеть правило, запрещающее писать 3 + 1

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 19:01 
Заслуженный участник
Аватара пользователя


30/01/06
02/09/19
70490
warlock66613 в сообщении #1344128 писал(а):
Обратите также внимание на запись 3 + 1 вместо просто 4: это снижает вероятность запутаться и забыть, что из четырёх байт только три можно задействовать для полезной информации.

Хороший совет! Спасибо!

(Хотя я бы сначала по убывающей использовал C++-style string<>, и буфер избыточного размера.)

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 19:56 
Заслуженный участник
Аватара пользователя


27/04/09
25194
Уфа
Может, тогда вообще

#define ZERO_SUFFIXED(n) ((n)+1)
char s[ZERO_SUFFIXED(3)];

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 20:56 
Заслуженный участник
Аватара пользователя


02/08/11
5647
arseniiv, интересный вариант. Но мне кажется, что такое увеличение степени абстракции и усиление связанности (раньше кусок кода был сам по себе, а теперь он связан с заголовочным файлом, в котором определён макрос) не оправдано. Если б я такое увидел в реальном проекте, я бы даже выругался.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней.  [ Сообщений: 102 ]  На страницу 1, 2, 3, 4, 5 ... 7  След.

Модераторы: Toucan, maxal, PAV, Karan, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group