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.
Здравствуйте, Edain, Вы писали:
E>(&a + sizeof(char))
С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.
Если какой-нибудь ретивый компилятор наоптимизирует что-то таким образом, что (c != a), то будет в полном праве так поступить.
Здравствуйте, achp, Вы писали:
A>Здравствуйте, Edain, Вы писали:
E>>(&a + sizeof(char))
A>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.
A>Если какой-нибудь ретивый компилятор наоптимизирует что-то таким образом, что (c != a), то будет в полном праве так поступить.
Тогда почему после ввода переменной типа char e;
и присвоения e *ptr; (уже после выполнения инкрементирования и декремента)
е тоже будет указывать на мусор в памяти?
Здравствуйте, Nortsx, Вы писали:
N>Тогда почему после ввода переменной типа char e; N>и присвоения e *ptr; (уже после выполнения инкрементирования и декремента) N>е тоже будет указывать на мусор в памяти?
Можно уточнить вопрос и конкретизировать его фрагментом кода?
Здравствуйте, 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
Здравствуйте, Edain, Вы писали:
E>...но это будет _не_ обязательно адрес переменной b, т.к. никто не гарантирует, что a и b будут в памяти расположены последовательно (или гарантирует?).
Для начала, никто не гарантирует, не только размещение переменной b в памяти, а не где-то ещё, в регистрах, например, или ещё где, так и вообще её существования...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, 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;
Здравствуйте, 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);
}
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.
Что означает зщапись например int& i = какому нить другмоу инту.
Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя.
Вот правда не понимаю
Здравствуйте, Masterkent, Вы писали:
E>>>(&a + sizeof(char))
A>>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.
M>Здесь как раз-таки всё законно:
Хм, действительно. Интересно, зачем такое безобразие сделано…
Здравствуйте, Nortsx, Вы писали:
N>Что означает зщапись например int& i = какому нить другмоу инту. N>Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя. N>Вот правда не понимаю
Почему нужно спрашивать на форуме то, что прописано в любом учебнике?