Member 13365663 Ответов: 3

Как эта программа выдает выходные данные на C++, пожалуйста, объясните


#include<iostream.h>
#include<conio.h>

class base
{
public:
    int bval;
    base()
    {
        bval=0;
    }
};

class deri:public base
{
public:
    int dval;
    deri()
    {
        dval=1;
    }
};

void SomeFunc(base *arr,int size)
{
    for(iont i=0;i<size;i++,arr++)
        cout<<arr->bval;
    cout<<endl;
}

int main()
{
    base BaseArr[5];
    SomeFunc(BaseArr,5);
    deri DeriArr[5];
    SomeFunc(DeriArr,5);
}


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

эта программа выдает результат в виде :
00000
01010

3 Ответов

Рейтинг:
2

Jochen Arndt

Это потому, что ваш SomeFunc() функция использует указатель на base класс.

В цикле используемый адрес переданного аргумента увеличивается на sizeof(base). Но для deri класс он должен быть увеличен на sizeof(deri) чтобы получить действительный указатель на следующий элемент. Потому что база имеет размер 4 байта / sizeof(int) и deri в два раза больше, указатель будет работать несинхронизированно.

Расположение памяти deri является:

int bval;
int dval;
Значения, к которым эффективно обращаются, затем:
Iteration  base      deri
0          bval[0]   bval[0] = 0
1          bval[1]   dval[0] = 1
2          bval[2]   bval[1] = 0
3          bval[3]   dval[1] = 1
4          bval[4]   bval[2] = 0


Рейтинг:
0

OriginalGriff

Просто: этот код не компилируется. Итак, то, что вы запускаете, - это вывод из другого набора кода. oint это не известный тип для начинающих.
Но если бы это было так, то он не сделал бы того, что вы думаете, и причина в этом:

void SomeFunc(base *arr,int size)
{
    for(iont i=0;i<size;i++,arr++)
        cout<<arr->bval;

deri DeriArr[5];
SomeFunc(DeriArr,5);
Когда вы передаете DeriArr в SomeFunc, он поступает как Base* - что вполне допустимо, так как имя массива является указателем на первый элемент в массиве, а Deri является производным от Base, поэтому указатель на Deri является допустимым указателем на базу.
Но затем вы увеличиваете указатель: arr++ как часть цикла for.
Что касается SomeFunc, то arr-это указатель на базу, поэтому ++ добавляет к указателю размер базы в байтах. Но Deri больше, чем Base - у него есть дополнительное целое число. Таким образом, приращение указателя не указывает на следующий элемент Deri, он указывает на следующий базовый элемент и заканчивается на полпути через экземпляр Deri. И вот: вы получаете результат, который видите.


Рейтинг:
0

Patrice T

Цитата:
Как эта программа выдает выходные данные на C++, пожалуйста, объясните

Посмотрите сами с помощью отладчика.
Существует инструмент, который позволяет вам видеть, что делает ваш код, его имя отладчик Это также отличный инструмент обучения, потому что он показывает вам реальность, и вы можете увидеть, какие ожидания соответствуют реальности.
Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик-Википедия, свободная энциклопедия[^]

Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010-YouTube[^]
Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.