2014 dxdy logo

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

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




На страницу 1, 2, 3, 4, 5 ... 7  След.
 
 Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 11:30 
Столкнулся с совершенно непонятным мне эффектом, работа оператора 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 
Для начала увеличьте длину буфера s до чего-нибудь более безопасного. Он у вас переполняется.

 
 
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 11:50 
realeugene
Спасибо, проблема решена

 
 
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 12:17 
Вот по причине таких проблем рекомендуется всегда передавать длину буфера явно. В частности, при использовании 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 

(Оффтоп)

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

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

(Оффтоп)

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

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

(Оффтоп)

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

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

(Оффтоп)

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

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

(Оффтоп)

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

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

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

(Оффтоп)

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

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

(Оффтоп)

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

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

(Оффтоп)

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

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

 
 
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 19:01 
Аватара пользователя
warlock66613 в сообщении #1344128 писал(а):
Обратите также внимание на запись 3 + 1 вместо просто 4: это снижает вероятность запутаться и забыть, что из четырёх байт только три можно задействовать для полезной информации.

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

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

 
 
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 19:56 
Может, тогда вообще

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

 
 
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 20:56 
arseniiv, интересный вариант. Но мне кажется, что такое увеличение степени абстракции и усиление связанности (раньше кусок кода был сам по себе, а теперь он связан с заголовочным файлом, в котором определён макрос) не оправдано. Если б я такое увидел в реальном проекте, я бы даже выругался.

 
 
 [ Сообщений: 102 ]  На страницу 1, 2, 3, 4, 5 ... 7  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group