Where is "int n" declared?

What am I missing? This sort.cpp from CppWOF CH 6 works fine. (I just commented out the Pause for Netbeans to be happy.)

I thought that you can't declare a variable as a parameter for a function, unless it's a pointer, if was not yet declared in some other location of the program (most generally main). If that is the case, then why are you allowed to use n as the parameter in the sort function?

Is it legal to "declare on the fly" in a function definition (line 4)? I thought that this was merely the declaration of the type of the parameter, not the actual variable passed in?

Many thanks in advance for explanations & or links to the same.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
  #include <iostream>
using namespace std;

void sort(int n);
void swap(int *p1, int *p2);

int a[10];

int main () {
    int i;

    for (i = 0; i < 10; i++) {
        cout << "Enter array element #" << i << ": ";
        cin >> a[i];
    }
    sort(10);

    cout << "Here are all the array elements, sorted:" << endl;
    for (i = 0; i < 10; i++)
        cout << a[i] << "  ";

    cout << endl;
  //  system("PAUSE");
    return 0;
}

// Sort array function: sort array named a, having n elements.
// 
void sort (int n) {
    int i, j, low;

    for(i = 0; i < n - 1; i++) {

        // This part of the loop finds the lowest
        //  element in the range i to n-1; the index
        //  is set to the variable named low.

        low = i;
        for (j = i + 1; j < n; j++)
            if (a[j] < a[low])
                low = j;

        // This part of the loop performs a swap if
        //  needed.

        if (i != low)
            swap(&a[i], &a[low]);
    }
}

// Swap function.
// Swap the values pointed to by p1 and p2.
//
void swap(int *p1, int *p2) {
    int temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}
At line 4 (the declaration), the name of the variable has no effect and is, in fact, optional. Only the type matters. At line 29, the definition, you have to give the parameter a name. Parameters can have any type and any valid name.
So the int n is not a variable at all, just the placeholder for the parameter of Sort(), right?
It is a variable within the scope of the function. It is initialized by whatever the caller uses as parameter when calling the sort. Yes, parameter is special, but a variable nonetheless. You could say that variable n is declared on line 29.

The p1 and p2 are variables too. Just like n, their value is initialized by whatever swap is called with.
Thanks eskiverto, the link was helpful, but the comments even more so.
So we have it working, & it sorts, mostly.
How can it sort some, but not all of the numbers.
The following code give this output (in Netbeans):

Here is the array in order: 3 3 1 5 2 34 45 56 56 78

Here is the array in order: 43 21 24 34 63 44 73 56 79 87

But we also got
Here is the array in order: 0 1 2 3 4 5 6 7 8 9
and
00 11 22 33 44 55 66 77 88 99

How can it sort some (times) but not all(always)?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
using namespace std;

void swap(int *p1, int p2);

void sort(int array_size);

int array[10];

void swap(int *p1, int *p2){
    int temporary;
    temporary = *p1;
    *p1 = *p2;
    *p2 = temporary;
}

void sort(int array_size){
    int loop_counter_1;
    int loop_counter_2;
    int lowest_array_element;

    //This loop sets loop_counter_1 to 0, 1, 2, 3, 4, 5, 6, 7, 8, & 9. n - 1??? n - 2???
    for(loop_counter_1 = 0; loop_counter_1 < array_size - 1; loop_counter_1++){
        lowest_array_element = loop_counter_1;

        for (loop_counter_2 = loop_counter_1 + 1; loop_counter_2 < array_size; loop_counter_2++){

            if (array[loop_counter_2] < array[lowest_array_element]){
                lowest_array_element = loop_counter_2;
            }

            //This if statement performs a swap if necessary.
            if (loop_counter_1 != lowest_array_element){
                swap(&array[loop_counter_1], &array[lowest_array_element]);
            }
        }
    }
}

int main(){

    int iNow;

    //This loop gets the values of all 10 elements of the array from the user.
    for (iNow = 0; iNow < 10; iNow++){
        cout << "Please input array element # " << iNow << ": ";
        cin >> array[iNow];
    }

    sort(10);   //This calls the sort function.

        cout << "Here is the array in order: ";
    //This loop outputs the elements of the array in order.
    for (iNow = 0; iNow < 10; iNow++){
        cout << array[iNow] << " ";
    }

return 0;
}
Last edited on
Should the if-clause on lines 33-35 really be within the inner loop?
That definitely helped, but I noticed that the swap was:
int p2 in stead of *p2.

It appears to be working now. Does it make sense that the missing * would mess up the swap?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
using namespace std;

void swap(int *p1, int *p2);

void sort(int array_size);

int array[10];

void swap(int *p1, int *p2){
    int temporary;
    temporary = *p1;
    *p1 = *p2;
    *p2 = temporary;
}

void sort(int array_size){
    int loop_counter_1;
    int loop_counter_2;
    int lowest_array_element;

    //This loop keeps track of all the elements of the array that have already been sorted.
    for(loop_counter_1 = 0; loop_counter_1 < array_size - 1; loop_counter_1++){
        lowest_array_element = loop_counter_1;

        //The inner loop looks to the next slot to the right (loop_counter_1 + 1) & does a search
        //for the next number that should be put into that slot.
        for (loop_counter_2 = loop_counter_1 + 1; loop_counter_2 < array_size; loop_counter_2++){

            if (array[loop_counter_2] < array[lowest_array_element]){
                lowest_array_element = loop_counter_2;
            }
        }

        //This if statement performs a swap if necessary.
        if (loop_counter_1 != lowest_array_element){
            swap(&array[loop_counter_1], &array[lowest_array_element]);
        }

    }
}

int main(){

    int iNow;

    //This loop gets the values of all 10 elements of the array from the user.
    for (iNow = 0; iNow < 10; iNow++){
        cout << "Please input array element # " << iNow << ": ";
        cin >> array[iNow];
    }

    sort(10);   //This calls the sort function.

        cout << "Here is the array in order: ";
    //This loop outputs the elements of the array in order.
    for (iNow = 0; iNow < 10; iNow++){
        cout << array[iNow] << " ";
    }

return 0;
}
Last edited on
You had essentially:
1
2
3
4
5
6
7
8
9
void swap(int *p1, int p2);
void swap(int *p1, int *p2);

// code that calls void swap(int *, int *)

void swap(int *p1, int *p2)
{
  // code
}

Lines 1 and 2 declare two functions with name "swap". That is function overloading.
When your code contains swap( foo, bar ); the compiler tries to match it to one of the functions based on the types of foo and bar.

When compiler has finished, the linker connects the call (line 4) to the implementation (lines 6-9) that matches the selected declaration (line 2).
If you had a call to swap(int*'int), then the linker would error on missing implementation.
You had no separate declaration for the int*p2, but luckily the implementation was before use and did serve as declaration. If it hadn't, then the compiler would have noticed the error of attempt to call swap(int*,int) while the declarations know only the swap(int*,int*); "cannot convert pointer to int".
Topic archived. No new replies allowed.