Member 10585568 Ответов: 4

Пожалуйста, объясните мне выход.я думаю, что выход должен быть 8, но это 10.почему он дает 10 в качестве выхода?


#include <iostream>

использование пространства имен std;

тап_п() {
int a[] = { 5,7,9,11,14};
int *p= a+2;
cout<<++*p++;
}

Что я уже пробовал:

Я думаю, что выход должен быть 8, но это 10.Почему он дает 10 в качестве выходного сигнала?

[no name]

Интересный. Пожалуйста, объясните, почему вы ожидаете 8. На данный момент я не понимаю, почему это должно быть 8 или 10.
См., например, это:Арифметика Указателей C++ [^]

Richard MacCutchan

Потому что это такой код, который только запутывает. Возьмите подходящую книгу по Си и изучите основы.

ZurdoDev

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

[no name]

Нет, не "справедливое замечание". Я думаю, что мы все должны были учиться, погружаясь в странные вещи. Разобраться в "странных" вещах поможет углубленное изучение.

[Edit] и называть ОП ребенком/идиотом-это далеко не честно!

Richard MacCutchan

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

[no name]

Совсем не мило. Пусть новички попробуют научиться... и не называйте новичков детьми/идиотами!

Richard MacCutchan

Смотрите мой ответ HappyFestivus.

[no name]

Прочитай. Но все же по крайней мере для меня интересующиеся глубиной датайлы хороший вопрос. Согласен, не актуально в производстве, но интересно погружаться в детали.
[Edit]и да, я думаю, что вы знаете, как читать мой странный английский, странный также и для меня, когда я снова читаю

Richard MacCutchan

Вот для чего нужен отладчик.

Member 10585568

Сэр,мне действительно очень жаль, если вы чувствуете раздражение/глупость/ребячество по этому вопросу. У меня нет никого, кто мог бы мне помочь. Вот я и решил добраться сюда.

Отныне я буду заботиться о том, чтобы публиковать свои сомнения, и я позабочусь о том, чтобы это не было ребячеством.

[no name]

Это далеко не детский вопрос! В противном случае на него должно быть легко ответить ;)

Richard MacCutchan

На этот вопрос можно легко ответить, фактически изучив язык и/или используя Google.

[no name]

После этого @Balboos дает объяснение, да, это легко. Почему вы заранее не дали такого простого решения?

Ладно, неприятный комментарий с моей стороны, но и что-то высокомерное с вашей стороны.

Richard MacCutchan

Нет. Я пытаюсь заставить "новичков" действительно правильно выучить язык, а не просто брать код из интернета, который они не понимают. В следующий раз, когда один из ваших аккаунтов будет взломан, скорее всего, это будет вина кого-то, кто получает работу разработчика, не зная, что он делает. Можно ли ожидать, что кто-то попытается починить тормоза на вашем автомобиле, если он не понимает принципов трения и несжимаемых жидкостей?

[no name]

Я не люблю драться. Я ценю ваши знания!

Richard MacCutchan

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

[no name]

Я согласен с этим

4 Ответов

Рейтинг:
8

Patrice T

Не объединяйте вещи в одну линию, если вы не понимаете, что вы объединяете.
Измените свой код на:

#include <iostream>
using namespace std;

int main() {
  int a[] = { 5,7,9,11,14};
  cout<<"A:" << *a << endl;
  int *p= a+2; // this is pointer arithmetic 
  cout<<"B:" << *p << endl;
  // the result comes from
  cout<<"C:" << ++(*p) << endl;
  cout<<++*p++;
}


[no name]

Извините, мои 3, но это сейчас лишнее и не объясняет, что и почему и что еще

Patrice T

Нет проблем, 3 нейтрален.
Мое решение находится в коде для выполнения.

Рейтинг:
2

OriginalGriff

Все просто: ты делаешь глупости!
Видеть здесь: Почему x = ++x + x++ дает мне неправильный ответ?[^]


[no name]

Не могли бы вы объяснить это подробнее на приведенном примере из ОП? На данный момент я действительно не понимаю, почему 8 или 10 должны быть результатом, проверяя это для целых чисел размером 2/4 байта. Любой намек приветствуется.

Dave Kreskowiak

Что тут объяснять? Реализация префиксных и постфиксных операторов никогда не была четко определена в исходной спецификации языка Си и поэтому полностью зависела от мнения людей, написавших свои компиляторы языка Си. Один и тот же код, скомпилированный двумя разными компиляторами языка Си, может привести к различным выходным данным.

Код, опубликованный OP, не имеет определенного правильного ответа, потому что код использует операторы, которые генерируют Различный машинный код, зависящий от используемого компилятора.

[no name]

- А что тут объяснять?"
О постфиксе здесь не может быть и речи (на мой взгляд), пожалуйста, постарайтесь быть конструктивным ;)

Dave Kreskowiak

Я был настроен конструктивно. Проблема в том, что вы не читали статью, на которую ссылался Грифф.

Member 10585568

Моя путаница не связана с префиксом или постфиксом.

Я был смущен значением a в операции *p=a+2.я думаю,что a должно быть 5(0-й элемент массива),но я получил 10 в качестве вывода, так что таким образом a равно 7(1-й элемент массива).Я просто хочу прояснить этот момент.

OriginalGriff

a - указатель на первый элемент (содержащий 5), поэтому a+2-указатель на третий элемент (содержащий 9).
Итак, p указывает на 9.
Потом все усложняется...:смех:

Member 10585568

Я полностью упустил эту концепцию.Спасибо, сэр ... и извините за эту ошибку..

Рейтинг:
2

Dave Kreskowiak

Добавьте пару строк cout к коду, а затем запустите код под отладчиком, поставив точку останова на первой строке под int main() Шаг за шагом просматривайте код в отладчике, изучая содержимое переменных до и после выполнения каждой строки кода, и должно стать очевидно, что происходит.

<pre>int main()
{
    int a[] = { 5, 7, 9, 11, 14 };

    int *p = a + 2;

    cout << *p << endl;

    cout << ++*p++ << endl;

    cout << *p << endl;
}

Отладчик-это инструмент для отладки вас и вашего понимания кода, а не самого кода. Вы должны научиться использовать этот инструмент, или вы просто будете гадать, что на самом деле делает ваш код.

То, как компилятор и процессор интерпретируют и выполняют код, может сильно отличаться от того, как вы интерпретируете и выполняете код в своей голове.


[no name]

Это конструктивно! Тем не менее о постфиксе не может быть и речи ;)
И все же не понимаю, почему выходит 10, скорее всего, мне нужно проверить MSB vs LSB?

Dave Kreskowiak

Нет, это не так. Операторы pre и postfix находятся в самом сердце этой проблемы. Именно они так сбивают с толку людей, которые смотрят на такой код и не могут понять, что происходит.

Основная проблема заключается не в том, каков правильный ответ. Проблема заключается в том, чтобы понять операторов, как они выполняют свою работу и, что более важно, когда они выполняют свою работу.

Ты слишком глубоко в это заглядываешь. Это не имеет ничего общего с MSB над LSB. Вы должны сделать именно то, что я описал в своем ответе.

[no name]

Но в случае, если я не применяю post fix, я получаю 10 *путаницы*

Dave Kreskowiak

Как я уже сказал, отладчик предназначен для отладки вас, а не кода.

[no name]

Я занимаюсь отладкой. Может быть, лучше сделать это завтра снова.... хммм
[Редактировать]
Проклятье, я не понимаю, в чем я ошибаюсь, пожалуйста, помогите, я всегда вижу 10 и не могу объяснить!


[Редактировать]
{ int a[] = { 5, 7, 9, 11, 14 };

int *p = a + 2;

int xP= *p;
если (xP) // xP покажет мне, чего я ожидаю, "9"
;

int xPP= ++*p;
если (xPP) // xPP показывает мне 10, не знаю почему, пожалуйста, объясните
;
}

Dave Kreskowiak

Вы вставили два других заявления cout?

Я уже говорил об этом: изучите содержимое переменных до и после выполнения строки кода.

[no name]

Пожалуйста, смотрите мой отредактированный комментарий. И я действительно ценю возможность учиться на этом.

Dave Kreskowiak

Вы вообще не читали статью Гриффа, на которую он ссылался, и, по-видимому, понятия не имеете, что делают префиксные и постфиксные операторы. Я настоятельно рекомендую прочитать эту статью.

[no name]

Просто скажи мне, почему 10 должно выйти... если ты это знаешь ;)

И как уже говорилось ранее, я все еще убежден, что пре/пост что бы то ни было здесь не считается. Просто опять же почему 10?

Dave Kreskowiak

Нет. Я могу указать вам на все, что говорит вам о том, как это работает. Единственное, чего я не могу сделать, так это понять это для тебя.

[no name]

*лол* "я могу указать тебе на все", потому что ты этого не знаешь. Счастливого вам эксперта...

[Редактировать]
Решение 3 объясняло мое отсутствие.

Dave Kreskowiak

О, я прекрасно это знаю. Я научил себя этому дерьму более 30 лет назад.

Я просто не собираюсь тебе его читать. Попроси свою маму сделать это, если ты этого хочешь.

[no name]

мне жаль тебя.

Member 10585568

Моя путаница не связана с префиксом или постфиксом.

Я был смущен значением a в операции *p=a+2.я думаю,что a должно быть 5(0-й элемент массива),но я получил 10 в качестве вывода, так что таким образом a равно 7(1-й элемент массива).Я просто хочу прояснить этот момент.

Dave Kreskowiak

a это указатель с адресом первого элемента в нем. Массивы в C/C++ основаны на нуле. Первым элементом в массиве всегда является[0], или, точнее, адрес первого элемента.

Когда ты увидишь a + 2 компилятор скрывает математику , которую он делает. Тип a это int. a + 2 становится начальным адресом массива plus (sizeof(int) * 2), давая вам адрес третьего элемента массива, а не второго. a + 2 вернется 9.

Рейтинг:
16

W∴ Balboos, GHB

Отложив все остальное в сторону, что не так-то просто

int *p=a+2; // Increments two sizeof(int) - that is, two elements NOT two bytes
Так, поскольку является адресом[0], то а+2 является адресом[2]
Это означает, что он указывает на 9.
Если вы увеличите 9, это даст вам 10.

Теперь в этом есть смысл? Хорошо. Сейчас идут исследования указывают арифметика и ее использование в С/С++. Это невероятно полезно, мощно, и, не овладев им, вы зря тратите свое время.


[no name]

О wtf, как я мог пропустить это, указатель против значения! Большое спасибо! Иногда (очень часто) объяснять это другими словами действительно решает конфликт :) теперь имеет смысл.

Dave Kreskowiak

Ха-ха-ха... все еще не так. a это указатель! Он содержит адрес первого значения в массиве. Когда вы добавляете к нему 2, Вы получаете адрес, увеличенный на (sizeof(int) * 2). Компилятор скрывает от вас эти мелкие детали, чтобы сделать код более легким для чтения, но труднее понять, что происходит за экраном.

О, и ты никогда не говорил, что это то, с чем у тебя были проблемы. Вы застряли на пре-и постфиксных операторах, о которых, по-видимому, никогда не читали статью, которая вдается в детали, которые вы здесь требуете!

[no name]

ха-ха, нет, нет: "вы застряли на пре-и постфиксных операторах". Пост-фикс, по крайней мере, здесь не может быть и речи. Если вы все еще думаете, что есть, у вас есть проблема с ними ;)
Я не первый, кто упоминает об этом: пожалуйста, ответьте соответствующим образом.
ПОЖАЛУЙСТА, ДА?

Dave Kreskowiak

Хахаха. Счастливой вам жизни.

Member 10585568

Спасибо большое .......сэр.

W∴ Balboos, GHB

Если на вопрос получен ответ, пожалуйста, отметьте принятый ответ.

Member 10585568

Я пропустил его полностью...извините