Good day! I am practicing sorting algorithms in C ++, and came across such a problem:

I create an array of X elements, given the X I enter through the keyboard. All this is done in the main() method.

 int length; cout << "How many elements do you want to add? Type here: "; cin >> length; int array[length]; 

After entering X I fill my array with a long X random numbers. And I bring to the screen:

 cout << "Your current array is:\n\n"; for(int i = 0; i < length; i++){ array[i] = rand() % 100; printf("%d ", array[i]); } 

Well, after that we see not sorted array ..

Next, I create a method that takes in parameters our array with my elements and sorts by the bubble method

 void sort(int array[]){ int length, temp, j; length = sizeof(array) / sizeof(*array); bool sort = true; while(sort){ j++; sort = false; for(int i = 0 ; i < length - j; i++){ if (array[i] > array[i+1]){ temp = array[i]; array[i] = array[i+1]; array[i+1] = temp; sort = true; } } } } 

Well, in the main() method I call this method ..

 main(){ //declare array sort(array); //output after sorting } 

But when I run the program, I see that my array is not sorted .. Where is my error? I know that if in Java to write such an implementation, then it will work .. But as I understood it just now, in C ++ it is necessary differently.

  • do not use printf use cout - JK_Action
  • @JK_Action Yes, I know, just printf is convenient for a bit) - E1mir
  • By studying the issue came to the conclusion that he was wrong. - JK_Action

2 answers 2

C ++ does not support variable-length arrays. There are separate compilers that have their own extensions of the C ++ language, which include such support, but it’s better not to rely on it. So this code

 int length; cout << "How many elements do you want to add? Type here: "; cin >> length; int array[length]; 

does not comply with C ++ standard.

You should dynamically allocate the array. For example,

 int *array = new int[length]; 

and on completion of the program to remove it

 delete [] array; 

When passing an array by value as an argument to a function, it is implicitly converted to a pointer to its first element. Therefore, this function declaration

 void sort(int array[]); 

equivalent to the following function declaration

 void sort(int *array); 

and declare the same function.

Inside this function

 void sort(int array[]){ int length, temp, j; length = sizeof(array) / sizeof(*array); //... 

sentence

  length = sizeof(array) / sizeof(*array); 

does not calculate the number of elements in the array as you think. It is equivalent to the following sentence.

  length = sizeof( int * ) / sizeof( int ); 

For example, if the size of the sizeof( int * ) pointer is 8 and the size of sizeof( int ) is 4, then you will end up with 2.

You should declare the function as

 void sort( int array[], int length ); 

or better yet

 void sort( int array[], size_t length ); 

Regarding bubble sorting, see my answer to SO Among other things, in your function you use the non-initialized variable j , which leads to unspecified program behavior

 int length, temp, j; ^^^ length = sizeof(array) / sizeof(*array); bool sort = true; while(sort){ j++; ^^^^ 

Note that the main function with no parameters must be declared in C ++ as

 int main() ^^^ 
  • Wow) Everything is so clear and clear) Yes, my style of code looks more like Java ... I only started working on C ++ for a week, and I don’t know how to write the rules and how to write it)) And all this is for boring laboratory work ... And as for the variable j I forgot to put 0 here) The program costs 0) - E1mir

As you yourself guessed, your main (but not the only) problem is that you incorrectly calculated the size of the array. If you write the output of the length variable to the console, you will immediately see it. I, for example, it is always equal to two.

Now how to deal with it. You are now, in fact, passing in a function pointer to the beginning of the array. Get in this situation the number of elements - no way.

You have already found one way out. Pass pointer to start and size:

 void sort(int *array, int size){ //... } int main(){ int arr[] = {1, 2, 3, 4}; sort(arr, sizeof(arr)/sizeof(int)); } 

You can proceed in the style of a standard library and pass a pointer to the first and to the next after the last elements:

 void sort(int *begin, int *end){ //... } int main(){ int arr[4] = {1, 2, 3, 4}; sort(&arr[0], &arr[4]); } 

Note that &arr[4] returns a pointer to a non-existing element. It can not be dereferenced. But in order to mark the end of the array, it will fit perfectly.

Well, the way for cool guys :). Link to array + templates:

 template<int size> void sort(int (&array)[size]){ //... } int main(){ int arr[] = {1, 2, 3, 4}; sort(arr); } 

I am sure at the initial stage you shouldn’t bother with this head, but agree that it looks cool. The compiler itself derived the size of the array, we didn’t even have to do anything.

  • Haha)) I agree) It looks really cool) But I don’t want to take root deeper in C ++, I’m used to Java that there are ready-made classes where you can take and write array.length and don’t have to bother with its long) And then you need to know its length To be engaged in magic) Yes and all the same) the main thing is that the problem is solved) and everyone is happy :)) - E1mir
  • one
    @KryTer_NexT, there are such classes in C ++. std::vector ( ArrayList in java), std::list ( LinkedList in java), std::set ( TreeSet in java), std::map ( TreeMap in java), std::unordered_set ( HashSet in java), std::unordered_map ( HashMap in java). There are still std::unordered_mulimap , std::mulimap , std::unordered_muliset and std::muliset , but I find it difficult to name their counterparts in java - yrHeTaTeJlb