ТУпейший вопрос про указатели
От: Nortsx  
Дата: 18.07.11 11:21
Оценка:
    char a = 'a';
    char b = 'b';
    char c;
    char d;
    char e;
    char* ptr = &a;
    c = *ptr++;
    d = *ptr--;


После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?
Re: ТУпейший вопрос про указатели
От: boot  
Дата: 18.07.11 11:26
Оценка: +1
Здравствуйте, Nortsx, Вы писали:

N>
N>    char a = 'a';
N>    char b = 'b';
N>    char c;
N>    char d;
N>    char e;
N>    char* ptr = &a;
N>    c = *ptr++;
N>    d = *ptr--;
N>


N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?


А так?
    char a = 'a';
    char b = 'b';
    char c;
    char d;
    char e;
    char* ptr = &a;
    c = *ptr++;
    d = *(--ptr);
Жизнеспособность прямо пропорциональна простоте!
Re: ТУпейший вопрос про указатели
От: savitar  
Дата: 18.07.11 11:27
Оценка:
Здравствуйте, Nortsx, Вы писали:

//c = *ptr++;
//d = *ptr--;
// 2 законтированные строчки можно переписать так:
c = *ptr;
++ptr;
d = *ptr;
--ptr;


Вопрос отпадает?
Re[2]: ТУпейший вопрос про указатели
От: Nortsx  
Дата: 18.07.11 11:30
Оценка:
Здравствуйте, savitar, Вы писали:

S>Здравствуйте, Nortsx, Вы писали:


S>
S>//c = *ptr++;
S>//d = *ptr--;
S>// 2 законтированные строчки можно переписать так:
S>c = *ptr;
S>++ptr;
S>d = *ptr;
S>--ptr;
S>


S>Вопрос отпадает?


Это логично, но разве унарные операторы в плюсах не выполняются справа налево?
http://www.cyberguru.ru/programming/cpp/cpp-programming-guide-page35.html здесь вроде так.
Что значит — сначала он должен инкрементировать а потом разыменовать.
Re: ТУпейший вопрос про указатели
От: blackhearted Украина  
Дата: 18.07.11 11:31
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>
N>    char a = 'a';
N>    char b = 'b';
N>    char c;
N>    char d;
N>    char e;
N>    char* ptr = &a;
N>    c = *ptr++;
N>    d = *ptr--;
N>


N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?


пост-декремент?
Re: ТУпейший вопрос про указатели
От: achp  
Дата: 18.07.11 11:41
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>d — указывают на пустую область памяти.


Во-первых, d не может ни на что указывать, т. к. не является указателем.

Во-вторых, непонятно, какой смысл вложен в словосочетание «пустая область памяти».

N>Почему?


Частный случай неопределённого поведения.
Re: ТУпейший вопрос про указатели
От: Edain Верблюд  
Дата: 18.07.11 12:24
Оценка: 1 (1) +1
Здравствуйте, Nortsx, Вы писали:

N>
N>    char a = 'a';
N>    char b = 'b';
N>    char c;
N>    char d;
N>    char e;
N>    char* ptr = &a;
N>    c = *ptr++;
N>    d = *ptr--;
N>


N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?


c будет иметь значение 'a', потому что сначала происходит разыменование, а потом инкремент (т.к. оператор ++ постфиксный). При этом ptr будет указывать на ячейку памяти, расположенную сразу за переменной a (&a + sizeof(char)), но это будет _не_ обязательно адрес переменной b, т.к. никто не гарантирует, что a и b будут в памяти расположены последовательно (или гарантирует?). Поэтому когда выполняется d = *ptr--, переменная d получает в качестве значения мусор, хранящийся по адресу &a + sizeof(char), а указатель вновь будет указывать на a.
Re[2]: ТУпейший вопрос про указатели
От: achp  
Дата: 18.07.11 12:31
Оценка:
Здравствуйте, Edain, Вы писали:

E>(&a + sizeof(char))


С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.

Если какой-нибудь ретивый компилятор наоптимизирует что-то таким образом, что (c != a), то будет в полном праве так поступить.
Re[3]: ТУпейший вопрос про указатели
От: Nortsx  
Дата: 18.07.11 12:36
Оценка:
Здравствуйте, achp, Вы писали:

A>Здравствуйте, Edain, Вы писали:


E>>(&a + sizeof(char))


A>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.


A>Если какой-нибудь ретивый компилятор наоптимизирует что-то таким образом, что (c != a), то будет в полном праве так поступить.


Тогда почему после ввода переменной типа char e;
и присвоения e *ptr; (уже после выполнения инкрементирования и декремента)
е тоже будет указывать на мусор в памяти?
Re[4]: ТУпейший вопрос про указатели
От: achp  
Дата: 18.07.11 12:37
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>Тогда почему после ввода переменной типа char e;

N>и присвоения e *ptr; (уже после выполнения инкрементирования и декремента)
N>е тоже будет указывать на мусор в памяти?

Можно уточнить вопрос и конкретизировать его фрагментом кода?
Re: ТУпейший вопрос про указатели
От: abrarov Россия http://asio-samples.blogspot.com/
Дата: 18.07.11 12:41
Оценка:
Здравствуйте, Nortsx, Вы писали:
N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?

char a = 'a';
char b = 'b';
char c;
char d;
char e;
char* ptr = &a;
c = *ptr++; // выражение ptr++ - это пост-инкремент. Поэтому *(ptr++) даст 'a'.            
d = *ptr--; // здесь уже ptr указывает на то, что лежало в стеке до того, как в стек была помещена переменная a 
            // (на x86 стек растет в сторону меньших адресов). Т.к. ptr-- тоже пост-инкремент, то
            // d будет указывать как раз таки на то самое, что было "положено" в стек, до появления переменной a.


Вообще пост-инкремент (и пре-инкремент) очень коварный. Рекомендую почитать про точки следования (C++ sequence point). Например, вот здесь.
Programs must be written for people to read, and only incidentally for machines to execute
Re[3]: ТУпейший вопрос про указатели
От: stapter  
Дата: 18.07.11 12:59
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>Это логично, но разве унарные операторы в плюсах не выполняются справа налево?

N>http://www.cyberguru.ru/programming/cpp/cpp-programming-guide-page35.html здесь вроде так.
N>Что значит — сначала он должен инкрементировать а потом разыменовать.
Эта тема должна все прояснить
Автор: Alex Dav
Дата: 20.02.07
Re[2]: ТУпейший вопрос про указатели
От: Erop Россия  
Дата: 18.07.11 13:38
Оценка: 1 (1) +2
Здравствуйте, Edain, Вы писали:

E>...но это будет _не_ обязательно адрес переменной b, т.к. никто не гарантирует, что a и b будут в памяти расположены последовательно (или гарантирует?).


Для начала, никто не гарантирует, не только размещение переменной b в памяти, а не где-то ещё, в регистрах, например, или ещё где, так и вообще её существования...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: ТУпейший вопрос про указатели
От: Nortsx  
Дата: 18.07.11 13:40
Оценка:
Здравствуйте, achp, Вы писали:

A>Здравствуйте, Nortsx, Вы писали:


N>>Тогда почему после ввода переменной типа char e;

N>>и присвоения e *ptr; (уже после выполнения инкрементирования и декремента)
N>>е тоже будет указывать на мусор в памяти?

A>Можно уточнить вопрос и конкретизировать его фрагментом кода?

Конкретизирую)

    char a = 'a';
    char b = 'b';
    char c;
    char d;
    char e;
    char* ptr = &a;
    c = *ptr++;
    d = *ptr--;
    e = *ptr;
Re[4]: ТУпейший вопрос про указатели
От: boot  
Дата: 18.07.11 14:12
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>Здравствуйте, achp, Вы писали:


A>>Здравствуйте, Edain, Вы писали:


E>>>(&a + sizeof(char))


A>>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.


A>>Если какой-нибудь ретивый компилятор наоптимизирует что-то таким образом, что (c != a), то будет в полном праве так поступить.


N>Тогда почему после ввода переменной типа char e;

N>и присвоения e *ptr; (уже после выполнения инкрементирования и декремента)
N>е тоже будет указывать на мусор в памяти?

Ну не совсем мусор.

#include <stdio.h>

int main(int argc, char* argv[])
{
    char a = 'a';
    char b = 'b';
    int c;
    int d;
    int e;
    char* ptr = &a;
    c = *ptr++;
    d = *ptr--;
    printf("c:%d\nd:%d", c, d);
}

D:\dev\prj\test>hz
c:97
d:-96

#include <stdio.h>

int main(int argc, char* argv[])
{
    char a = 'a';
    char b = 'b';
    int c;
    int d;
    int e;
    char* ptr = &b;
    c = *ptr++;
    d = *ptr--;
    printf("c:%d\nd:%d", c, d);
}

D:\dev\prj\test>hz
c:98
d:97
Жизнеспособность прямо пропорциональна простоте!
Re[3]: ТУпейший вопрос про указатели
От: Masterkent  
Дата: 18.07.11 14:32
Оценка: 6 (1)
achp:

E>>(&a + sizeof(char))


A>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.


Здесь как раз-таки всё законно:

C99 — 6.5.6 Additive operators — p.7:

For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.


C++03 — 5.7 Additive operators — p.4:

For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

Re[2]: И еще один
От: Nortsx  
Дата: 18.07.11 20:05
Оценка:
Что означает зщапись например int& i = какому нить другмоу инту.
Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя.
Вот правда не понимаю
Re[4]: ТУпейший вопрос про указатели
От: achp  
Дата: 19.07.11 12:10
Оценка:
Здравствуйте, Masterkent, Вы писали:

E>>>(&a + sizeof(char))


A>>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.


M>Здесь как раз-таки всё законно:


Хм, действительно. Интересно, зачем такое безобразие сделано…
Re[3]: И еще один
От: achp  
Дата: 19.07.11 12:12
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>Что означает зщапись например int& i = какому нить другмоу инту.

N>Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя.
N>Вот правда не понимаю

Почему нужно спрашивать на форуме то, что прописано в любом учебнике?
Re[6]: ТУпейший вопрос про указатели
От: achp  
Дата: 19.07.11 12:12
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>Конкретизирую)


N>
N>    char a = 'a';
N>    char b = 'b';
N>    char c;
N>    char d;
N>    char e;
N>    char* ptr = &a;
N>    c = *ptr++;
N>    d = *ptr--;
N>    e = *ptr;
N>


И что? Что-то поменялось?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.