Софтуерно Инженерство
Loading...
+ Нов въпрос
zlobjul avatar zlobjul 4 Точки

Промяна на размера на масив

Здравейте , 

Мъча се над 1 задача от 2ри урок на C++ Fundamentials. Искам да направя въвеждането на данни за масивите като функция .

Въпросът ми е следния , в долуописания код как да "разширя" масива във функцията след като потребителя подаде стойност от конзолата? 

За момента този код във функцията "реже" големината на array-a защото му се подават нулеви стойности преди това. 

#include<iostream>
using namespace std;

void arrayInput(int num, int arr[], int arrSize ){

    cout << "Please enter the length of Array" << num << ": ";
    cin >> arrSize;

//Тук искам да сменя размера на масива arr[arrSize] и накрая функцията да върне в length1 стойността въведена от потребителя arrSize. 

    cout << "Please enter "<< arrSize << " numbers, separated by spaces: " ;


    for ( int i = 0; i < arrSize ; i++) {
        cin >> arr[i];
        }


}

void checkEqual(int arr1[], int len1, int arr2[], int len2){
int eqIndex = 0;


if (len1 != len2) {
    cout << "Not equal" << endl;
    return;
}
else {
    for (int i = 0 ; i <= len1 ; i++ ){
        if (arr1[i] == arr2[i]){
                eqIndex++;
        }
    }
}
if ( eqIndex == len1  ){
    cout << "Equal" << endl;
}
else{
    cout << "Not equal" << endl;

}


}

int main() {

int length1,length2;
int array1[]{};
int array2[]{};

arrayInput(1,array1,length1);
for ( int i =0; i < length1 ; i++){
        cout << array1[i];
}
arrayInput(2,array2,length2);
for ( int i =0; i < length2 ; i++){
        cout << array2[i];
}
checkEqual(array1,length1,array2,length2);
return 0;
}
 

 

 

Благодаря ! 

Тагове:
0
C++ Fundamentals 25/11/2017 10:19:42
georgi.stef.georgiev avatar georgi.stef.georgiev 906 Точки
Best Answer

Здравей,

В лекцията споменах, че в C++ няма начин да промениш размера на такъв масив (всъщност и в други езици като Java и C# не е възможно това). Този вид масиви винаги стоят с размера, с който са създадени първоначално (а този размер според C++ стандартите трябва да е константно число, въпреки че повечето компилатори приемат и променлива).

За да постигнеш това, което искаш, функцията ти трябва да използва std::vector (в този случай std::vector<int>). В C++ няма друг вариант ако искаш паметта ти да бъде управлявана автоматично.

Ако държиш да ползваш масив, а не vector, по принцип съществува вариант - динамично заделяне на памет с new, запазване в pointer и връщане на pointer-а, след което ползвателя трябва да каже delete[] на този pointer (когато вече не го използва). Също така променливата arraySize която ползваш трябва да е int&, за да може като я промени функцията промяната да се отрази на променливата в main, не само вътре в arrayInput().

Pointer (указател на български) е променлива, която сочи към адрес в паметта. На този адрес може да има едно нещо или да има начало на масив от неща (съответно pointer-ът може да се третира като масив). new заделя "динамична" памет, тоест памет която не се трие автоматично след като излезе от блокът, в който е била заделена (нормалните променливи - "автоматичната" памет - се трие в момента в който блокът в който са създадени приключи).

Ето горе-долу как би изглеждало това, което искаш да направиш, с динамична памет и указатели:

int* readArray(int& arraySize) {
  cin >> arraySize; // NOTE: arraySize is a reference, so this changes the caller's variable
  
  int* array = new int[arraySize];
  for (int i = 0; i < arraySize; i++) {
    cin >> array[i]; // any int* can be used like an int[] - just watch out for the index and size
  }

  return array; // we are returning the pointer to the start of the array, arraySize gives us the length of that array
}

int main() {
  int readArraySize; // this will be filled-in by the readArray(int&) function
  int* array = readArray(readArraySize);

  // example: print out array
  for (int i = 0; i < readArraySize; i++) {
    cout << array[i] << " ";
  }

  // DO STUF WITH array ...

  // NOTE: this is very important to do - we are no longer using array. 
  // That means we need to delete it's memory, because otherwise that memory will stay, 
  // even though we are no longer using it (not doing delete when we have to is called a "memory leak")
  delete[] array;

  return 0;
}

И разбира се това е доста повече писане (и по-голям шанс за грешки) отколкото просто да прочетеш масива като vector:

vector<int> readArray() {
  vector<int> array;
  int size;
  cin >> size;

  for (int i = 0; i < size; i++) {
    int number;
    cin >> number;
    array.push_back(number);
  }

  return array;
}

int main() {
  vector<int> array = readArray();

  // example: print out array
  for (int i = 0; i < array.size(); i++) {
    cout << array[i] << " ";
  }

  return 0;
}

Всичките тези неща с pointer-и, new, delete и динамична памет са извън програмата на този курс за съжаление. В този курс ще водим фундаменталните неща за C++ - всичко, което ви е нужно да пишете работещи и пълноценни програми. Обаче няма да преподаваме по-напреднали неща като работа с паметта, указатели, наследяване в ООП и подобни. Ако трябва да направя аналогия, този курс ви е като шофьорски курс за лек автомобил - минимумът, за да можете да шофирате правилно и без да блъснете някого, но ви трябва още доста материал ако искате да сте състезатели във формула 1. Предишния вариант на този курс ги имаше всички тези неща и материалът беше твърде много за времето, което имахме, оттам и опростяването на материала в този курс - ако искаш да разгледаш по-подробно тези неща свързани с работата с памет, поглени предишното издание: https://softuni.bg/trainings/1573/cpp-programming-february-2017

 

Поздрави,

Жоро

3
25/11/2017 15:06:41
zlobjul avatar zlobjul 4 Точки

Благодаря !  

Да , след като догледах лекцията на запис  , стигнах и до векторите :). 

 

0
zlobjul avatar zlobjul 4 Точки

Пак съм аз :)

Този код крашва когато въведа първо число , разгледах го , но не разбирам защо се чупи? 

 

#include<iostream>
#include<vector>
using namespace std;

vector<int> arrayInput(int num){
    vector<int> arr;
    int arrSize;

    cout << "Please enter the length of Array" << num << ": ";
    cin >> arrSize;

    cout << "Please enter "<< arrSize << " numbers, separated by spaces: " ;


    for ( int i = 0; i < arrSize ; i++) {
        cin >> arr[i];
        }
return arr;
}

void checkEqual(vector<int> arr1, int len1, vector<int> arr2, int len2){
int eqIndex = 0;


if (len1 != len2) {
    cout << "Not equal" << endl;
    return;
}
else {
    for (int i = 0 ; i <= len1 ; i++ ){
        if (arr1[i] == arr2[i]){
                eqIndex++;
        }
    }
}
if ( eqIndex == len1  ){
    cout << "Equal" << endl;
}
else{
    cout << "Not equal" << endl;

}


}

int main() {

vector<int> array1 = arrayInput(1);
vector<int> array2 = arrayInput(2);

checkEqual(array1,array1.size(),array2,array2.size());
return 0;
}
 

0
georgi.stef.georgiev avatar georgi.stef.georgiev 906 Точки

Oops... кодът, който съм ти дал е грешен.

vector-ът няма никакви елементи първоначално, тоест няма как да му се прави cin >> array[i], защото array.size() == 0, съответно няма елементи 0, 1, 2...

Във вектор за да се появят елементи се ползва .push_back(), като съответно първия път се добавя 0-я елемент, следващия път 1-я и т.н.

Тоест в този цикъл не трябва да правиш cin >> array[i], а трябва да правиш int number; cin >> number; array.push_back(number);

Сега ще го редактирам в първоначалния отговор

0