Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Hagrael
БТР - мой друг
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
#1

Странное поведение - C++

10.06.2012, 11:35. Просмотров 549. Ответов 5
Метки нет (Все метки)

Здравствуйте еще раз Теперь возникла другая непонятка. Есть класс StringParser, объекты которого умеют разбивать строку на подстроки, разделенные запятыми. Всякий раз, когда вы вызываете метод .getNextPart(), он возвращает вам следующую подстроку. Описывается класс StringParser в файле StringParser.h:
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
using namespace std;
 
class StringParser {
    private:
        char *str, *seperators;
        int position;
        bool isSeperator(int seperatorPosition) {
            for (int i = 0; seperators[i] != '\0'; i++) {
                if (str[seperatorPosition] == seperators[i])
                    return true;
            }
 
            return false;
        }
    public:
        StringParser (char* newStr) {
            str = newStr;
            seperators = new char[1];
            seperators[0] = ',';
            position = 0;
        }
        char* getNextPart () {
            int partLength = 0;
            while (!isSeperator(position+partLength) and str[position+partLength] != '\0') {
                partLength++;
            }
 
            char* part = new char[partLength+1];
            for (int i = 0; i < partLength; i++) {
                part[i] = str[position+i];
            }
            part[partLength] = '\0';
 
            position += partLength+1;
 
            return part;
        }
};
Сам класс работает, вроде, исправно, однако есть одна странность.
Когда я пишу в главном файле программы так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include "StringParser.h"
using namespace std;
 
int main () {
    StringParser parser("1, 2, 3");
    cout << parser.getNextPart();
    cout << parser.getNextPart();
    cout << parser.getNextPart();
 
    return 0;
}
то все работает, как надо, на экран выводится "1 2 3" (пробелы parser не пропускает, т. к. они не являются разделителями, разделителем является только запятая).
Но когда я пишу так:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "StringParser.h"
using namespace std;
 
int main () {
    StringParser parser("1, 2, 3");
    cout << parser.getNextPart() << parser.getNextPart() << parser.getNextPart();
 
    return 0;
}
то на экран выводится " 3 21", т. е. все выводится в обратном порядке. Почему так?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.06.2012, 11:35
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Странное поведение (C++):

Странное поведение new - C++
Объясните почему оператор new выделяет неверное количество памяти? # include &lt;iostream&gt; using namespace std; char* interpitator( int...

Странное поведение программы - C++
Перечитываю Герберт Шилдт: С++ базовый курс. Простая программа: #include &lt;iostream&gt; using namespace std; int main() { ...

Странное поведение присваивания - C++
class Lexem { public: uint id; uint value; uint line; uint pos; bool operator==(int a){ return a...

Странное поведение string - C++
Здравствуйте. Сейчас я пытаюсь скомпилировать под Windows проект, который ранее писался под Linux. Делаю я это с помощью MinGW от...

Странное поведение функции - C++
Здравствуйте! Я взялась за реализацию метода Крылова для нахождения коэффициентов характеристического полинома. Написала программу, но...

Странное поведение компилятора - C++
Всем привет! Я конечно понимаю что нужно выкладывать минимальный код повторяющий мою проблему но он будет достаточно грамосток т.к. в...

5
Somebody
2791 / 1602 / 147
Регистрация: 03.12.2007
Сообщений: 4,199
Завершенные тесты: 1
10.06.2012, 11:40 #2
C++
1
cout << parser.getNextPart() << parser.getNextPart() << parser.getNextPart();
это
C++
1
operator<<(operator<<(operator<<(cout, parser.getNextPart()), parser.getNextPart()), parser.getNextPart());
А порядок вычисления аргументов функций может быть любой, не обязательно слева направо. Раздели на три отдельных выражения.
1
Hagrael
БТР - мой друг
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
11.06.2012, 12:12  [ТС] #3
По-моему, самый первый вызов должен быть в самой глубине, т. е. в подчеркнутом месте:
operator<<(operator<<(operator<<(cout, parser.getNextPart()), parser.getNextPart()), parser.getNextPart());
Вначале произойдет вызов метода .getNextPart() в этом месте, потом то, что он вернет отправится в функцию operator<<, а после то, что вернет функция operator<<, пойдет в "более внешнюю" функцию operator<<.
0
Somebody
2791 / 1602 / 147
Регистрация: 03.12.2007
Сообщений: 4,199
Завершенные тесты: 1
11.06.2012, 15:58 #4
http://www.open-std.org/jtc1/sc22/open/n2356/expr.html#expr.call
8 The order of evaluation of arguments is unspecified. All side effects
of argument expression evaluations take effect before the function is
entered. The order of evaluation of the postfix expression and the
argument expression list is unspecified.
И, так как параметры в стек обычно заталкиваются справа налево, вполне предсказуемо, что компилятор выбрал такой порядок.
0
Hagrael
БТР - мой друг
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
12.06.2012, 11:45  [ТС] #5
Не очень понял
Т. е. вначале в память записываются 3 значения, которые возвращает функция .getNextPart() при 3-х вызовах, а потом в самый внешний вызов подставляется 1-е значение, в более внутренний - 2-е и в самый глубокий - 3-е?

Если так, то почему тогда такой код выводит на экран "12"?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
 
int A ();
int B ();
 
int main () {
    cout << A() << B();
 
    return 0;
}
 
int A () {
    return 1;
}
 
int B () {
    return 2;
}
0
soon
2542 / 1307 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
12.06.2012, 12:04 #6
Hagrael, вы неправильно поняли. Это более наглядно
C++
1
2
3
4
5
6
7
8
#include <iostream>
 
int main()
{
    int a = 5;
    std::cout << a << ' ' << ++a << std::endl;
    return 0;
}
0
12.06.2012, 12:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.06.2012, 12:04
Привет! Вот еще темы с ответами:

Странное поведение указателя - C++
Здравствуйте, наткнулся на непонятное мне поведение указателя или точнее менеджера памяти. Есть код: #include &lt;iostream&gt; #include...

Странное поведение cin - C++
Перегружаю оператор ввода следующим образом: #include &lt;iostream&gt; using namespace std; class Vector2D { public: ...

Странное поведение транслятора - C++
В следуюшем примере код компилируется нормально, но объект класса b не содается (пробывал на Visual studio 10 и на Borland builder 5), что...

Странное поведение программы - C++
Здравствуйте, у меня проблема. В силу какой-то причины результатом вычисления выражения при значениях PA и PB равных 0 и 1 соответственно,...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru