C ++ Pointer (Array) - PullRequest
       5

C ++ Pointer (Array)

0 голосов
/ 10 марта 2020

Вот код моего урока

#include<iostream>
using namespace std;

int main()
{
    int arr[5] = {8,2,9,4,5},a,b,*ptr;
    int c = 5;

    ptr = arr;
    a = *ptr + 10;
    ptr = &c;   
    ptr += 2;
    cout<<*(ptr+1);
}

Я немного запутался, почему вывод равен 9. Когда ptr указывает на c, что оценивается 5, как может увеличить указатель +2, так как c не является массивом?

Ответы [ 5 ]

2 голосов
/ 10 марта 2020

Неопределенное поведение

Давайте разберем это:

int arr[5] = {8,2,9,4,5},a,b,*ptr;
int c = 5;

ptr = arr;      // ptr = address of arr[0]
a = *ptr + 10;  // a = (arr[0] + 10) = (8 + 10) = 18
ptr = &c;       // ptr = address of c
ptr += 2;       // UNDEFINED BEHAVIOR, c is not an array
cout<<*(ptr+1); // COULD PRINT ANYTHING

Не то, что мы установили неопределенное поведение, юристы по языку не могут подать в суд на меня, чтобы объяснить что может происходить:

Переменные main возможно складываются в стек следующим образом. Для этого простого примера удобно, чтобы элементы в стеке были целыми числами:

0x100 c 
0x104 arr[0]
0x108 arr[1]
0x10C arr[2]
0x110 arr[3]
0x114 arr[4]
0x118 a
0x11C b
0x120 ptr // address of the variable ptr, not what ptr points to

Следовательно, ptr+2 - это тот же адрес, что и arr [1] в массиве, который содержит значение "2 ». И тогда дополнительным выражением (ptr+1) является адрес arr [2], который содержит значение 9.

Но это потому, что вам повезло. Любая другая система или компилятор может взломать sh программу или сделать свет тусклым в вашем доме. Такова природа неопределенного поведения.

0 голосов
/ 10 марта 2020

Вывод вашей программы не детерминирован c. ptr, указывающий на c, был увеличен на 2. Поскольку ptr не указывал на непрерывную структуру памяти (например, массив), невозможно определить, на что указывает ptr после приращения. Так как это указатель на int, каждый шаг будет вызывать его переход на sizeof (int). При разыменовании ptr после приращения будет пытаться прочитать следующий размер байтов (int) как int. Таким образом, вы можете получить любое значение мусора.

0 голосов
/ 10 марта 2020

Я думаю, что вам не хватает * в ptr

#include<iostream>
using namespace std;


int main()
{
    int arr[5] = {8,2,9,4,5},a,b,*ptr;
    int c = 5;

    ptr = arr;
    a = *ptr + 10;
    ptr = &c;
    (*ptr) += 2;
    cout<<*(ptr+1);
}

Будет напечатано 8, но поведение вашей программы не определено из-за этой строки

  ptr += 2; 
0 голосов
/ 10 марта 2020

Ну, указатель not указывает на c.

, когда вы сделали ptr += 2;, указатель увеличился с c и теперь указывает на область памяти, имеющую значение мусора.

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

0 голосов
/ 10 марта 2020

То, что вы делаете, является неопределенным поведением

#include<iostream>
using namespace std;

    int main()
    {
        int arr[5] = {8,2,9,4,5},a,b,*ptr;
        int c = 5;

        ptr = arr;//here ptr points to the first element in the array
        a = *ptr + 10;
        ptr = &c;   //ptr points to an integer having no relation to the array
        ptr += 2;//ptr points to a position in the memory after the integer c by 2 places 
                 //(note that this place may not be allocated (undefined behavior) )
        cout<<*(ptr+1);//(ptr+1) points to a place after the integer c by three places 
                    //and then dereferenced (this in undefined behavior because this place
                   // may not be allocated and you dereferenced it.) 
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...