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

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

Войти
Регистрация
Восстановить пароль
 
 
bigibug
0 / 0 / 0
Регистрация: 03.04.2014
Сообщений: 3
#1

Загадка указателей - C++

03.04.2014, 23:06. Просмотров 688. Ответов 20
Метки нет (Все метки)

Здравствуйте =) Привел меня к Вам следующий вопрос.
Поступило задание составить программу для решения квадратного уровнения, используя указатели.
В процессе работы наткнулся на то что, казалось бы, одно и тоже (по смыслу) выдает разные результаты.
Преподаватель работу принял, но разницу не смог обьяснить. А я теперь ночами спать не могу, понять хочу что не так сделал. =) Единственная разница выделена жирным шрифтом.
Подскажите, пожалуйста, почему 2 следующие программы выдают столь различные результаты?
Листинг 1
Кликните здесь для просмотра всего текста
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
]#include<iostream>
#include<math.h>
using namespace std;
int main()
{
    int *p=new int[3],i,j=0;
    double x1,x2,d;
    char *t="abc";
    char *q=t;
    while (*q) 
    {
    cout<<*q++<<"=";
   [B] cin>>*(p+j);j++;[/B]
    for (i=0;i<3;i++) cout<<*(p+i)<<endl;     
    }
    d=pow(p[1],2)-4*p[0]*p[2];
    cout<<"d="<<d<<endl;
    if (d>=0) {x1=(-p[1]+sqrt(d))/2*(p[0]);
               x2=(-p[1]-sqrt(d))/2*(p[0]);
               cout<<"x1="<<x1<<endl<<"x2="<<x2;
        }
    else cout<<"net corney";
    delete [] p;
}

Результат 1
Кликните здесь для просмотра всего текста

a=1
1
0
0
b=5
1
5
0
c=4
1
5
4
d=9
x1=-1
x2=-4

Листинг 2
Кликните здесь для просмотра всего текста
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
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
    int *p=new int[3],i,j=0;
    double x1,x2,d;
    char *t="abc";
    char *q=t;
    while (*q) 
    {
    cout<<*q++<<"=";
   [B] cin>>*p++;[/B]
    for (i=0;i<3;i++) cout<<*(p+i)<<endl;     
    }
    d=pow(p[1],2)-4*p[0]*p[2];
    cout<<"d="<<d<<endl;
    if (d>=0) {x1=(-p[1]+sqrt(d))/2*(p[0]);
               x2=(-p[1]-sqrt(d))/2*(p[0]);
               cout<<"x1="<<x1<<endl<<"x2="<<x2;
        }
    else cout<<"net corney";
    delete [] p;
}

Результат 2
Кликните здесь для просмотра всего текста

a=1
0
0
1035
b=5
0
1035
892547121
c=4
1035
892547121
842086196
d=6ю53828e+17
x1=1.72275e+10
x2=-8.1967e+11
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.04.2014, 23:06
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Загадка указателей (C++):

по поводу указателей. Как правильно задавать массив указателей и его удалять? - C++
Т.е., например создаю указатель: TPoint *p_Point=NULL; а если массив? TPoint *p_MassPoint; //=?; как массив обнулить не ясно ...

Почему в сортировке указателей на объекты в вызове функции используются адреса объектов, а не указателей? - C++
Доброго времени суток! Рассматриваю пример (из Лафоре) сортировки массива указателей на объекты, для чего используются указатели на...

Создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей - C++
Задача: создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей. Вернуть адрес...

Объяснить различия в работе указателей на целое число и указателей на const char (строки в стиле Си) - C++
Уважаемые программисты, возникло несколько вопросов касательно указателей. Почему при выводе указателя на int нужна звёздочка (*), а...

Создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей - C++
Нужно создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей. Эта специализация...

Различия указателей char* от указателей других типов - C++
Помогите пожалуйста разобраться! Прочитал раздел про указатели и даже вроде бы понял. Что касается указателей на тип int. Но что...

20
monolit
186 / 185 / 22
Регистрация: 24.03.2011
Сообщений: 669
Завершенные тесты: 1
03.04.2014, 23:26 #2
Все потому, что во втором случае ты указатель на массив просто-напросто теряешь (p - изменяется!!!). Т.е. p теперь указывает не на то, что должен (начало массива из интов) - на место за массивом, а там мусор, вообще говоря. Ну по результатам видно и так)

C++
1
2
3
int *cur = p;
------
cin>>*cur++;
Так получишь то, что тебе нужно.
0
Dani
1393 / 637 / 57
Регистрация: 11.08.2011
Сообщений: 2,295
Записей в блоге: 2
Завершенные тесты: 1
03.04.2014, 23:27 #3
cin>>*p++;
Здесь сначала выполнится постфиксный инкремент, указатель изменит свое значение, а затем этот увеличенный указатель будет разыменован.
0
monolit
186 / 185 / 22
Регистрация: 24.03.2011
Сообщений: 669
Завершенные тесты: 1
03.04.2014, 23:28 #4
Цитата Сообщение от Dani Посмотреть сообщение
Здесь сначала выполнится постфиксный инкремент, указатель изменит свое значение, а затем этот увеличенный указатель будет разыменован.
Не в том дело... тем более это неверно.
1
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
03.04.2014, 23:31 #5
Изменяете сам указатель, поэтому потом он "указывает" черт знает куда.

Добавлено через 1 минуту
Цитата Сообщение от monolit Посмотреть сообщение
Не в том дело...
как раз в этом! В куске кода
C++
1
cin>>*(p+j)
указатель p не изменяется, а в
C++
1
cin>>*p++;
изменяется и сам указатель
0
Dani
1393 / 637 / 57
Регистрация: 11.08.2011
Сообщений: 2,295
Записей в блоге: 2
Завершенные тесты: 1
03.04.2014, 23:33 #6
Цитата Сообщение от monolit Посмотреть сообщение
Не в том дело... тем более это неверно.
Это почему еще?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
03.04.2014, 23:42 #7
Цитата Сообщение от Dani Посмотреть сообщение
Это почему еще?
думаю, было пропущено несколько слов из предложения
Цитата Сообщение от Dani Посмотреть сообщение
Здесь сначала выполнится постфиксный инкремент, указатель изменит свое значение, а затем этот увеличенный указатель будет разыменован.
0
Dani
1393 / 637 / 57
Регистрация: 11.08.2011
Сообщений: 2,295
Записей в блоге: 2
Завершенные тесты: 1
03.04.2014, 23:42 #8
Цитата Сообщение от monolit Посмотреть сообщение
тем более это неверно
Понял, не так написал: указатель увеличится, но разыменуется еще старый указатель, т.к. инкремент постфиксный.
0
monolit
186 / 185 / 22
Регистрация: 24.03.2011
Сообщений: 669
Завершенные тесты: 1
03.04.2014, 23:43 #9
как раз в этом! В куске кода
Я понимаю) Но тогда вторая часть фразы
а затем этот увеличенный указатель будет разыменован
здесь не нужна, ибо она ситуацию не проясняет - а только уводит внимание (с разыменованием у него все нормально, и заполнением массива тоже - вы это и так знаете) Вот на это я и указал. Тем более с порядком операций он все-таки ошибся)
Да и вообще, не о чем тут говорить - на пустом месте такая дискуссия развернулась.

Кликните здесь для просмотра всего текста

Цитата Сообщение от Croessmah Посмотреть сообщение
изменяется и сам указатель
Это в самом первом посте я и написал)
0
bigibug
0 / 0 / 0
Регистрация: 03.04.2014
Сообщений: 3
04.04.2014, 09:44  [ТС] #10
Ага, значит вводя *p++ я получаю не выражение *(p+1), указывающее на адрес следующего элемента массива p[], а, грубо говоря, указатель на 'p+1' значение которого впринципе фиг пойми какое. Я правильно понял?
0
aLarman
643 / 564 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
Завершенные тесты: 1
04.04.2014, 09:48 #11
Цитата Сообщение от bigibug Посмотреть сообщение
значение которой впринципе фиг пойми какое
ну не фиг пойми, а p + sizeof(тип на который указывает указатель)
Цитата Сообщение от bigibug Посмотреть сообщение
Я правильно понял?
да операция p+1, вернет указатель на следцщий элемент массива, а операция, p++, вернет указатель на текущий элемент, и изменит р, р теперь будет указывать на следующий элемент
0
monolit
186 / 185 / 22
Регистрация: 24.03.2011
Сообщений: 669
Завершенные тесты: 1
04.04.2014, 10:03 #12
aLarman, Вы видать не совсем внимательно прочитали его последний вопрос, так что понял он неправильно.
Цитата Сообщение от bigibug Посмотреть сообщение
указатель на 'p+1' значение которого впринципе фиг пойми какое
Запись cin>>*p++ эквивалентна следующему:
C++
1
2
cin>>*p;
p += 1;
Но в предыдущем тебе правильно ответили...
0
aLarman
643 / 564 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
Завершенные тесты: 1
04.04.2014, 10:23 #13
Цитата Сообщение от monolit Посмотреть сообщение
Вы видать не совсем внимательно прочитали его последний вопрос, так что понял он неправильно.
по-моему под
Цитата Сообщение от monolit Посмотреть сообщение
указатель на 'p+1' значение
он имел ввиду p+=1; но вообще говоря, кто знает как он понял...
0
bigibug
0 / 0 / 0
Регистрация: 03.04.2014
Сообщений: 3
04.04.2014, 10:35  [ТС] #14
Ясно, спасибо огромное за помощь =) Всем добра!
0
intern
15 / 15 / 6
Регистрация: 30.03.2014
Сообщений: 74
Завершенные тесты: 2
04.04.2014, 16:28 #15
В продолжение темы есть вопрос:
C++
1
2
int arr[] = {7, 8, 9};
cout << *++arr;
требует l-значение, а
C++
1
2
3
int arr[] = {7, 8, 9};
int *parr = arr;
cout << *++parr;
работает нормально
0
04.04.2014, 16:28
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.04.2014, 16:28
Привет! Вот еще темы с ответами:

Как обойтись без указателей и указателей на указатель? - C++
Ибо не совсем выходит понять,что на что тут указывает #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;stdlib.h&gt; using namespace...

Создание массивов указателей на массивы указателей - C++
Помогите в решении задачи: создал массив указателей на массивы указателей на строки, но компилятор ругается на то что не может...

Добавление нового указателя в конец массива указателей, удаление указанного элемента, добавление указателей - C++
Здравствуйте. Помогите, пожалуйста, разобраться с одним большим заданием. Задание пока в процессе написания, но уже наверное есть ошибки....

Массив указателей на массив строк и сортировка массива указателей - C++
Добрый день. Поступил вопрос. Есть задача. У нас встроенный массив char mass;.Мы вводим строки до тех пор, пока не будет заполнен массив...


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

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

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