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 921 Точки
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 921 Точки

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
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.