Как использовать указатели на массивы? - PullRequest
1 голос
/ 04 марта 2020

Так что в настоящее время я все еще запутался в использовании указателей и ссылок, и я не знаю, правильно ли то, что я делаю. Моя программа представляет собой калькулятор, который хранит все, что вводит пользователь. Существует возможность, что пользователю будет задан вопрос, хочет ли он / она просматривать историю, и если он / она хочет ее, программа покажет все данные, которые он / она вводит. И мне нужно использовать указатели и ссылки в моей программе, но Я все еще не понимаю, как использовать указатели и ссылки на массив. Вот моя инициализация:

int main() {
  int size = 1, fNum[size], sNum[size];
  char oprtn[size], answer;
  ;
  float result[size];
  int *ptrf = &fNum[size];
  int *ptrs = &sNum[size];
  char *ptro = &oprtn[size];
  float *ptrRes = &result[size];
  while (true) {
    cout << "=====CALCULATOR=====\n\n";
    cout << "ENTER TWO NUMBERS:" << endl;
    while (!(cin >> *ptrf >> *ptrs)) {
      system("cls");
      cout << "INVALID INPUT. PLEASE ENTER TWO NUMBERS:\n";
      cin.clear();
      cin.ignore(2);
    }
    cout << endl;
    do {
      cout << "Choose Operation to be Used: \n"
           << "   +   --- Addition  \n"
           << "   -   --- Subtraction   \n"
           << "   *   --- Multiplication   \n"
           << "   /   --- Division   \n"
           << "   %   --- Remainder   \n";
      cout << "Answer: ";
      cin >> answer;
      cout << endl;
      switch (answer) {
        case '+':
          cout << "ADDITION\n";
          break;
        case '-':
          cout << "SUBTRACTION\n";
          break;
        case '*':
          cout << "MULTIPLICATION\n";
          break;
        case '/':
          cout << "DIVISION\n";
          break;
        case '%':
          cout << "REMAINDER\n";
          break;
        default:
          answer = false;
          system("cls");
          cout << "PLEASE ENTER A VALID ANSWER. CHOOSE BELOW.\n\n";
          cout << "FIRST NUMBER: " << *ptrf << endl;
          cout << "SECOND NUMBER: " << *ptrs;
          cout << endl << endl;
          continue;
      }
    } while (!answer);
    cout << "DO YOU WANT TO TRY AGAIN? (Y / N): ";
    cin >> answer;
    switch (answer) {
      case 'Y':
      case 'y':
        system("cls");
        continue;
      default:
        cout << "VIEW HISTORY? (Y / N): ";
        cin >> answer;
        switch (answer) {
          case 'Y':
          case 'y':
            cout << "HISTORY\n\n";
            break;
          default:
            return 0;
        }
    }
  }
}

Ответы [ 2 ]

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

Это недопустимый код C ++:

  int size = 1, fNum[size], sNum[size];   // wrong: C++ forbids Variable Length Arrays (1)
  char oprtn[size], answer;               // ditto...
  ;
  float result[size];                     // ditto...
  int *ptrf = &fNum[size];         // wrong: this syntax makes ptrf points one past end of array (2)
  int *ptrs = &sNum[size];         // ditto...
  char *ptro = &oprtn[size];       // ditto...

(1): VLA является языковой концепцией C. Некоторые компиляторы (g cc и CLang) допускают его в качестве расширения , но это бесполезно в C ++ из-за контейнеров из стандартной библиотеки

(2): идиоматика c способ инициализации указателя на начало массива - это просто int *ptrf = Num;. При использовании в качестве значения r (короче справа от знака =) массив распадается на указатель на свой первый элемент. Таким образом, он читает (int *) ptr = &(fNum[0]);: ptr является указателем на int, а его начальное значение является адресом первого элемента массива fNum

1 голос
/ 04 марта 2020
fNum[size] 

- это массив из одного целого числа.

int *ptrf = &fNum[size];

Указатель на один элемент после последнего элемента этого массива, поэтому он находится за пределами доступа, это неопределенное поведение .

Поскольку он имеет только один элемент, вы объявляете его массивом бессмысленным.

Указатель на начало массива будет:

int *ptrf = fNum;

Или

int *ptrf = &fNum[0];

Затем вы можете циклически перебирать массив, увеличивая указатель ptrf++.

Чтобы получить указатель на переменную:

int x;
int *ptr = &x;

Итак, объявления и присваивания переменных:

int size = 1, fNum[size], sNum[size];
char oprtn[size], answer;
float result[size];
int *ptrf = &fNum[size];
int *ptrs = &sNum[size];
char *ptro = &oprtn[size];
float *ptrRes = &result[size];

То же, что и:

int fNum, sNum;
char oprtn, answer;;
float result; 
int *ptrf = &fNum;
int *ptrs = &sNum;
char *ptro = &oprtn;
float *ptrRes = &result;

Тем не менее, в C ++ есть несколько более приятных контейнеров данных, которые вы можете использовать, например, std::vector или std::array.

Последнее замечание: массивы переменной длины (fNum[size]) запрещены в C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...