Pointers Are Teh Devil!
OttoDestruct
Join Date: 2002-11-08 Member: 7790Members

in Off-Topic
<div class="IPBDescription">C++ questions</div> Erm... I have no idea whats wrong with my prog. Every tutorial I've read on pointers has just ended up screwing my program up worse, so heres the code and errors which I'm getting. Any suggestions are appreciated. Oh yea.. the program is supposed to create an array of random numbers, then the two pointers of arrays are supposed to have each element point to the array, putting it in an order. Right now I've just got it to do a normal sort with values, not pointers.
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
#include <time.h>
#include <iostream.h>
#include <math.h>
int main (void)
{
// Local Declaration
int array[5];
int *pAscending = new int[5];
int *pDescending = new int[5];
// Prototype Declaration
void generatearray(int[], &int, &int);
void sortascend (int[], &int);
void sortdescend (int[], &int);
void displayarray (int[], &int, &int);
generatearray(array, &pAscending, &pDescending);
sortascend (array, &pAscending);
sortdescend (array, &pDescending);
displayarray (array, &pAscending, &pDescending);
}
void generatearray (int array[], int *pAscending, int *pDescending)
{
int i = 0;
srand(clock());
for (i = 0; i < 5; i++)
array[i] = (rand()%98+1); // for
for (i=0; i < 5; i++)
*(pAscending+i) = array[i]; // for
for (i=0; i < 5; i++)
*(pDescending+i) = array[i]; // for
} // generatearray
void sortascend (int array[], int *pAscending)
{
int i = 0;
int temp = array[0];
void exchangelargest (int*, int, int);
for (i = 0; i < 5; i++)
exchangelargest (&pAscending, i, temp);
} // sortascend
void exchangelargest (int *pAscending, int i, int temp)
{
int temp2;
for (i=1;i < 5; i++)
{
if (temp > (*(pAscending+i)))
{
temp2 = *(pAscending+i);
*(pAscending+i) = temp;
temp = temp2;
} // if
} // for
} // exchangelargest
void sortdescend (int array[], int *pDescending)
{
int i = 0;
int temp = array[0];
void exchangesmallest (int*, int, int);
for (i = 0; i < 5; i++)
exchangesmallest (int &pAscending, int i, int temp);
} // sortdescend
void exchangesmallest (int *pAscending, int i, int temp)
{
int temp2;
for (i=1;i < 5; i++)
{
if (temp < (*(pAscending+i)))
{
temp2 = *(pAscending+i);
*(pAscending+i) = temp;
temp = temp2;
} // if
} // for
} // sortascend
void displayarray (int array[], int *pAscending, int *pDescending)
{
int i;
cout << "Program by Aaron Friedley" << endl << "Ascending" <<"\tOriginal"
<< "\tDescending" << endl;
for (i = 0; i < 5; i++)
{
cout << *(pAscending+i) << "\t" << array[i] << "\t" << *(pDescending+i)
<< endl;
}
}
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
These are the errors I get:
<!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->
cxx: Error: hwk04.cxx, line 13: expected a type specifier
void generatearray(int[], &int, &int);
----------------------------^
cxx: Error: hwk04.cxx, line 13: expected a type specifier
void generatearray(int[], &int, &int);
----------------------------------^
cxx: Error: hwk04.cxx, line 14: expected a type specifier
void sortascend (int[], &int);
--------------------------^
cxx: Error: hwk04.cxx, line 15: expected a type specifier
void sortdescend (int[], &int);
---------------------------^
cxx: Error: hwk04.cxx, line 16: expected a type specifier
void displayarray (int[], &int, &int);
----------------------------^
cxx: Error: hwk04.cxx, line 16: expected a type specifier
void displayarray (int[], &int, &int);
----------------------------------^
cxx: Error: hwk04.cxx, line 46: argument of type "int **" is incompatible
with parameter of type "int *"
exchangelargest (&pAscending, i, temp);
--------------------^
cxx: Error: hwk04.cxx, line 71: type name is not allowed
exchangesmallest (int &pAscending, int i, int temp);
---------------------^
cxx: Error: hwk04.cxx, line 71: identifier "pAscending" is undefined
exchangesmallest (int &pAscending, int i, int temp);
--------------------------^
cxx: Error: hwk04.cxx, line 71: type name is not allowed
exchangesmallest (int &pAscending, int i, int temp);
--------------------------------------^
cxx: Error: hwk04.cxx, line 71: too few arguments in function call
exchangesmallest (int &pAscending, int i, int temp);
------------------------------------------^
cxx: Error: hwk04.cxx, line 71: expected a ")"
exchangesmallest (int &pAscending, int i, int temp);
------------------------------------------^
cxx: Info: 12 errors detected in the compilation of "hwk04.cxx".
<!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
#include <time.h>
#include <iostream.h>
#include <math.h>
int main (void)
{
// Local Declaration
int array[5];
int *pAscending = new int[5];
int *pDescending = new int[5];
// Prototype Declaration
void generatearray(int[], &int, &int);
void sortascend (int[], &int);
void sortdescend (int[], &int);
void displayarray (int[], &int, &int);
generatearray(array, &pAscending, &pDescending);
sortascend (array, &pAscending);
sortdescend (array, &pDescending);
displayarray (array, &pAscending, &pDescending);
}
void generatearray (int array[], int *pAscending, int *pDescending)
{
int i = 0;
srand(clock());
for (i = 0; i < 5; i++)
array[i] = (rand()%98+1); // for
for (i=0; i < 5; i++)
*(pAscending+i) = array[i]; // for
for (i=0; i < 5; i++)
*(pDescending+i) = array[i]; // for
} // generatearray
void sortascend (int array[], int *pAscending)
{
int i = 0;
int temp = array[0];
void exchangelargest (int*, int, int);
for (i = 0; i < 5; i++)
exchangelargest (&pAscending, i, temp);
} // sortascend
void exchangelargest (int *pAscending, int i, int temp)
{
int temp2;
for (i=1;i < 5; i++)
{
if (temp > (*(pAscending+i)))
{
temp2 = *(pAscending+i);
*(pAscending+i) = temp;
temp = temp2;
} // if
} // for
} // exchangelargest
void sortdescend (int array[], int *pDescending)
{
int i = 0;
int temp = array[0];
void exchangesmallest (int*, int, int);
for (i = 0; i < 5; i++)
exchangesmallest (int &pAscending, int i, int temp);
} // sortdescend
void exchangesmallest (int *pAscending, int i, int temp)
{
int temp2;
for (i=1;i < 5; i++)
{
if (temp < (*(pAscending+i)))
{
temp2 = *(pAscending+i);
*(pAscending+i) = temp;
temp = temp2;
} // if
} // for
} // sortascend
void displayarray (int array[], int *pAscending, int *pDescending)
{
int i;
cout << "Program by Aaron Friedley" << endl << "Ascending" <<"\tOriginal"
<< "\tDescending" << endl;
for (i = 0; i < 5; i++)
{
cout << *(pAscending+i) << "\t" << array[i] << "\t" << *(pDescending+i)
<< endl;
}
}
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
These are the errors I get:
<!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->
cxx: Error: hwk04.cxx, line 13: expected a type specifier
void generatearray(int[], &int, &int);
----------------------------^
cxx: Error: hwk04.cxx, line 13: expected a type specifier
void generatearray(int[], &int, &int);
----------------------------------^
cxx: Error: hwk04.cxx, line 14: expected a type specifier
void sortascend (int[], &int);
--------------------------^
cxx: Error: hwk04.cxx, line 15: expected a type specifier
void sortdescend (int[], &int);
---------------------------^
cxx: Error: hwk04.cxx, line 16: expected a type specifier
void displayarray (int[], &int, &int);
----------------------------^
cxx: Error: hwk04.cxx, line 16: expected a type specifier
void displayarray (int[], &int, &int);
----------------------------------^
cxx: Error: hwk04.cxx, line 46: argument of type "int **" is incompatible
with parameter of type "int *"
exchangelargest (&pAscending, i, temp);
--------------------^
cxx: Error: hwk04.cxx, line 71: type name is not allowed
exchangesmallest (int &pAscending, int i, int temp);
---------------------^
cxx: Error: hwk04.cxx, line 71: identifier "pAscending" is undefined
exchangesmallest (int &pAscending, int i, int temp);
--------------------------^
cxx: Error: hwk04.cxx, line 71: type name is not allowed
exchangesmallest (int &pAscending, int i, int temp);
--------------------------------------^
cxx: Error: hwk04.cxx, line 71: too few arguments in function call
exchangesmallest (int &pAscending, int i, int temp);
------------------------------------------^
cxx: Error: hwk04.cxx, line 71: expected a ")"
exchangesmallest (int &pAscending, int i, int temp);
------------------------------------------^
cxx: Info: 12 errors detected in the compilation of "hwk04.cxx".
<!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
Comments
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->void generatearray(int[], &int, &int);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->void generatearray (int array[], int *pAscending, int *pDescending)<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
I''m pretty sure that your prototype should be:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->void generatearray(int[], int*, int*);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
(BTW, you also had the synax wrong for the other form, it should have been:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->void generatearray(int[], int&, int&);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->, but thats probably not what you want)
EDIT: Oh, and IIRC the array[] syntax is not supported in C (except in the main), you have to take it as int** to get the pointer to the array (which is actually a pointer).
EDIT 2: I might be wrong about all this, I haven't used pointers a whole lot in a while.
{
(some stuff in here)
(note lack of return statement)
}<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->You've got main listed as an int, but you give no return value. From what I understand, you can't omit that return statement unless you declare void main(). Also, there shouldn't be anything inside the parentheses. You've got "void" in there, and I think when you do that, the compiler recognizes what you're doing as a function protype or definition, rather than a call.
PS: I usually put my function prototypes outside main. I don't know if that would help, but it couldn't hurt to try.
First, change your prototypes to be in the format
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->void functionname(int[] var, int *var, int *var)<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
as suggested erlier. Next, wherever you call these functions, remove the '&' before the variable name. Such as:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->exchangelargest (&pAscending, i, temp);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
becomes:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->exchangelargest (pAscending, i, temp);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
Last but not least, fix the call in the for loop in sortdescend by removing the type specifiers from it:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->exchangesmallest (int &pAscending, int i, int temp);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
becomes:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->exchangesmallest (pAscending, i, temp);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
This left me with errors related to my compiler, so it should compile for you. Note that just because it compiles doesn't mean that it won't crash while running, just that there are no syntactical errors.
EDIT: oh, except that one related to pAscending being undeclared somewhere. Did you mean pDescending?
<!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->You've got "void" in there, and I think when you do that, the compiler recognizes what you're doing as a function protype or definition, rather than a call.<!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
This depends on the compiler, most don't care. I'm not sure which is the actually standard syntax.
EDIT 2: I'm not sure how this is supposed to output, but I didn't get any crashes so the pointer logic seems good.
First of all, this block is troubling me:
<!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->int array[5];
int *pAscending = new int[5];
int *pDescending = new int[5];
<!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
What you're doing here is declaring three arrays of five integers each. One of which is normal, two of which you're allocating yourself. You haven't freed the memory for the two arrays you've allocated anywhere that I can see, and that's a bad thing. Also, there's no reason for you to have allocated the memory yourself, rather than just used arrays (and I have a suspicion that you didn't mean to make two more arrays at all). [edit]On a second look, you did mean to, so never mind. You still don't need to allocate the arrays yourself, and I'll tell you why later on[/edit]
<!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin--> void generatearray(int[], &int, &int);
void sortascend (int[], &int);
void sortdescend (int[], &int);
void displayarray (int[], &int, &int);
generatearray(array, &pAscending, &pDescending);
sortascend (array, &pAscending);
sortdescend (array, &pDescending);
displayarray (array, &pAscending, &pDescending);
<!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
Whoa. Whoa whoa. Stop. Major problems in here, and it's definately because you're having trouble understanding pointers.
Firstly, your prototypes are different from what you're passing to them. Secondly, they're incorrect. Let's take the first one.
The prototype is <span style='font-family:Courier'>void generatearray(int[], &int, &int);</span>. The parameters are an integer array and two integer <b>reference variables</b>. You've called it as <span style='font-family:Courier'>(array, &pAscending, &pDescending);</span>, passing it an integer array (ok), and two <b>integer addresses</b>.
I'll stop here and give you a brief rundown of pointers, reference variables, arrays and addresses.
Pointers are always referred to as <span style='font-family:Courier'>type *</span>. So an integer pointer is <span style='font-family:Courier'>int *</span>. If you want to pass a pointer, the prototype should have a pointer in it; ie <span style='font-family:Courier'>int *</span> and not <span style='font-family:Courier'>int &</span>. As you should know, pointers point to a variable through its memory address.
The ampersand operator, when <i>used on an existing variable</i> (note: NOT in a variable declaration) returns the <i>address</i> of that variable. That's important. I just mentioned that pointers refer to a variable through their memory address; this is how you get that address. You might have something like this:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->int someNumber = 5;
int *somePointer; //declare an integer pointer
somePointer = &someNumber; /*assign the memory address of someNumber to somePointer, allowing somePointer to point to it*/<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
Now the value of <span style='font-family:Courier'>somePointer</span> is some crazy hexadecimal value which is the memory location of the variable <span style='font-family:Courier'>someNumber</span>. To get at the value of whatever <span style='font-family:Courier'>somePointer</span> is pointing at, you stick an asterisk in front of it. Like this:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->int anotherNumber;
anotherNumber = *somePointer; //somePointer still pointing at someNumber
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
<span style='font-family:Courier'>anotherNumber</span>'s value will now be 5. This is exactly the same as:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
anotherNumber = someNumber;<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
Next. There are such things as reference variables, which you're using (I think by accident). You <i>declare</i> a reference variable the same way you declare a pointer, except you use an ampersand instead of an asterisk. Using reference variables instead of pointers, our above example would be:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->int someNumber = 5;
int &someReference = someNumber; //declare an integer reference var and initialise it to refer to someNumber
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
From now on, whenever we use <span style='font-family:Courier'>someReference</span>, it is <i>exactly</i> as if we'd used <span style='font-family:Courier'>someNumber</span>. It's like a pointer, but without the pointer syntax (and, as far as I know, no way of changing it to point to something else, which is why I assigned it on initialisation).
So we don't need the * operator to get at what <span style='font-family:Courier'>someReference</span> refers to.
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->int anotherNumber;
anotherNumber = someReference;<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
Next. Arrays are pointers. Pointers are arrays. They are the same thing. When you have this code...
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->int array[10];<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
...the variable <span style='font-family:Courier'>array</span> is an integer pointer, pointing at the first integer in a contiguous block of ten integers (uh, "contigous" means one after another, with no gaps in between).
Because C is nice to you (ha!. well, nice <i>this time</i>), it lets you use alternate syntax if you want to clarify that your pointer is supposed to be an array. That's what you're using. For example, your prototype
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->void generatearray(int[], &int, &int);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
is identical exactly to the prototype
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1--> void generatearray(int*, &int, &int);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
in every way. Except of course that yours is better, because it makes it clear to the reader that the integer pointer is supposed to be an array.
Now, let's have another read through and see what else I can spot...
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
void generatearray(int[], &int, &int); //prototype
generatearray(array, &pAscending, &pDescending);//function call
void generatearray (int array[], int *pAscending, int *pDescending) //definition
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
You're saying three different things, when they're all supposed to be the same. Your prototype is for an integer array and two integer reference variables. You're passing it an integer array and two <i>addresses of integer arrays</i>. When you're implementing it, you're asking for an integer array and two integer pointers (in other words, three integer arrays).
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1--> for (i=0; i < 5; i++)
*(pAscending+i) = array[i]; // for<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
This is completely valid. It's a bit convoluted (which might have been the point of the exercise, I don't know.). Just to clarify, what you've done is identical to:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
for(i=0; i < 5; i++)
pAscending[i] = array[i];
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
I'm not saying change it. I'm just making you aware of it ;).
I'm pretty sure that the compile errors you're getting are because of the stuff I mentioned earlier. You're getting mixed up about the syntax of declaring, defining and using pointers (and arrays). I haven't traced the execution of your algorithm to verify that it's correct (that's your job :P) but I think that's your compiler errors fixed. Oh, and remember to <span style='font-family:Courier'>delete</span> that memory you allocated in <span style='font-family:Courier'>main</span>. Or better yet don't allocate it in the first place and just use normal arrays.
{
(some stuff in here)
(note lack of return statement)
}<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->You've got main listed as an int, but you give no return value. From what I understand, you can't omit that return statement unless you declare void main(). Also, there shouldn't be anything inside the parentheses. You've got "void" in there, and I think when you do that, the compiler recognizes what you're doing as a function protype or definition, rather than a call. <!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
*Bzzt*. Wrong, but thanks for playing.
The C standard mandates that <span style='font-family:Courier'>main</span> must be declared as returning an int. Yes, MSVC++ is <i>wrong and bad</i> for allowing you to declare it as void. That is <i>non-standard. Do <b>not</b> do it.</i>
However, the C standard also mandates that you don't have to put in the return value for main if you don't want to. Often, although you have to declare main as returning int, you never actually want it to return anything (like here. There are times when you <i>do</i> want it to return something, but that's another story.)
By the way, it's less typing to do it the standard way. <span style='font-family:Courier'>int</span> is less typing than <span style='font-family:Courier'>void</span> <!--emo&;)--><img src='http://www.unknownworlds.com/forums/html//emoticons/wink.gif' border='0' style='vertical-align:middle' alt='wink.gif' /><!--endemo-->
Finally, the business about putting <span style='font-family:Courier'>void</span> in the parameter list, while deprecated, is syntactically valid and can be used anywhere you'd ordinarily have an empty parameter list. It's basically used just to make it blindingly obvious that the function doesn't take any parameters. I don't use it, myself. Oh, in some instances <span style='font-family:Courier'>main</span> actually does take (two very specific) parameters, but it's perfectly legal to treat it as if it doesn't if you don't want them.
*Bzzt*. Wrong, but thanks for playing.
The C standard mandates that <span style='font-family:Courier'>main</span> must be declared as returning an int. Yes, MSVC++ is <i>wrong and bad</i> for allowing you to declare it as void. That is <i>non-standard. Do <b>not</b> do it.</i>
However, the C standard also mandates that you don't have to put in the return value for main if you don't want to. Often, although you have to declare main as returning int, you never actually want it to return anything (like here. There are times when you <i>do</i> want it to return something, but that's another story.) <!--QuoteEnd--> </td></tr></table><div class='postcolor'> <!--QuoteEEnd-->
Huh. Learn something new everyday.
I learned that the C standard is structured stupidly, and internally inconsistent. Shocking.
*Bzzt*. Wrong, but thanks for playing.
The C standard mandates that <span style='font-family:Courier'>main</span> must be declared as returning an int. Yes, MSVC++ is <i>wrong and bad</i> for allowing you to declare it as void. That is <i>non-standard. Do <b>not</b> do it.</i>
However, the C standard also mandates that you don't have to put in the return value for main if you don't want to. Often, although you have to declare main as returning int, you never actually want it to return anything (like here. There are times when you <i>do</i> want it to return something, but that's another story.) <!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
Huh. Learn something new everyday.
I learned that the C standard is structured stupidly, and internally inconsistent. Shocking. <!--QuoteEnd--> </td></tr></table><div class='postcolor'> <!--QuoteEEnd-->
Weell... there <i>are</i> reasons. Well, one main one: efficiency. C (and C++) were built with the underlying philosophy of "you only pay for what you use".
In this case it's because all programs return a code to the operating system when they terminate. That's the return value of main. So, main always does return an int. Similarly, sometimes you run a program with command line parameters - those parameters can get passed to main().
It's just that if you don't have any use for returning a specific error code to the OS, C does it for you and returns a "move along, people, there's nothing to see here" code if you don't specify one. And you don't always need the command line parameters, so if you don't ask for them then C doesn't waste resources retrieving them for you. It might not be completely consistent, but it isn't irrational. And above all else, it's efficient.
What were we talking about again?
P.S. I <b>finally</b> get what pointers are.
What were we talking about again?
P.S. I <b>finally</b> get what pointers are. <!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
with a void main you just return like this:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->return;<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
This works for any void function. But like scorpy said, its not standard in main(), so don't do it.
Personally I rather like using the void keyword for parameters. If you'd ever seen my code you'd probably see why. <--- Is a code neat freak.
Yes, but he's passing arrays. You can't pass arrays any other way than by reference. Not primitive arrays, anyway.
That was part of the assignment to use the two pointer arrays <!--emo&;)--><img src='http://www.unknownworlds.com/forums/html//emoticons/wink.gif' border='0' style='vertical-align:middle' alt='wink.gif' /><!--endemo-->
<!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->Whoa. Whoa whoa. Stop. Major problems in here, and it's definately because you're having trouble understanding pointers.
<!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
Correct <!--emo&:D--><img src='http://www.unknownworlds.com/forums/html//emoticons/biggrin.gif' border='0' style='vertical-align:middle' alt='biggrin.gif' /><!--endemo--> Like I said I've looked at five or six tutorials all telling me to do different stuff, thus why I posted here.
<!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->
That's what you're using. For example, your prototype
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->void generatearray(int[], &int, &int);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
is identical exactly to the prototype
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1--> void generatearray(int*, &int, &int);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
in every way. Except of course that yours is better, because it makes it clear to the reader that the integer pointer is supposed to be an array
<!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
Yea the professor wanted us to use pointer notatin instead of array notation, teaching us good programming habits and all that.
*Edit*
You wouldnt happen to be able to give me a crash course on how to create a pointer within my pointer arrays would you?
Hm...
Well, the short answer is that you can't. An integer, a pointer to an integer, and a pointer to a pointer to an integer (or a pointer to an integer array, if it hurts your brain less <!--emo&;)--><img src='http://www.unknownworlds.com/forums/html//emoticons/wink.gif' border='0' style='vertical-align:middle' alt='wink.gif' /><!--endemo-->) are considered completely seperate data types.
My understanding is that you want something like this:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
int *allocatedArray = new int[10];
int someNumber;
int *somePointer = &someNumber;
//and then, some arbitrary element...
allocatedArray[5] = somePointer //make one of the elements a pointer
//and the rest of the elements in the array are normal ints
delete[] allocatedArray;
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
C doesn't let you have different data types in the same array. Of course, there are ways around that (in pure C they mostly invove void pointers. Nasty stuff which I'm not very experienced with.)
But if that's not what you meant, and you just wanted a pointer to point to an element of the array, you can just use it and it'll work:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
int someArray[10];
int *somePointer = &someArray[5];
//somePointer now points at the sixth element of someArray
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
Or maybe you wanted an array of arrays?
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
int **arrayOfArrays = new (int*)[10]; //not actually sure of the syntax here. hehe.
for(int i=0; i<10;++i)
arrayOfArrays[i] = new int[10];
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
Unfortunately, I'm not absolutely sure of the syntax myself. I can tell you this much, though...
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->int *pAscending = new int[5];<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
This declares an integer pointer, allocates a block of five integers, and makes the pointer point to the beginning of them.
I think what you want is something like this:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->int *ascending[5];<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
That is, an array of five integer pointers. Nothing's being dynamically allocated (I'm pretty sure you didn't want that in the first place). Each element of <span style='font-family:Courier'>ascending</span> is itself a pointer, and can be made to point to any integer the same as a normal pointer.
And, technically, <span style='font-family:Courier'>ascending</span> is itself an <span style='font-family:Courier'>int *</span> pointer, pointing to the first <span style='font-family:Courier'>int *</span> in a contiguous block of five <span style='font-family:Courier'>int *</span>s. That makes it an <span style='font-family:Courier'>int **</span>.
...I've just done a quick test, and I was right about the syntax. Good luck <!--emo&:)--><img src='http://www.unknownworlds.com/forums/html//emoticons/smile.gif' border='0' style='vertical-align:middle' alt='smile.gif' /><!--endemo-->
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->int **AoP; //A pointer to an array of pointers
int *x; //An int pointer
int main(void)
{
AoP = new int * [5]; //Points the pointer to a newly allocated array of int pointers
AoP[1] = new int; //Assigns the second pointer in the array pointed to by AoP to point to x
}<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
I can't help you with your algorithm, since I don't know what its supposed to be doing....
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
void sortascend (int array[], int **pAscending)
{
int i;
void exchangelargest (int[], int**, int);
for (i = 0; i < 5; i++)
exchangelargest (array, pAscending, i);
} // sortascend
void exchangelargest (int array[], int **pAscending, int i)
{
int walker;
int largest;
int *temp = *pAscending;
largest = i;
for (walker = i+1; walker <= 5; walker++)
{
if (array[walker] > array[largest])
largest = walker; // if
temp = *(pAscending+i);
*(pAscending+i) = *(pAscending+largest);
*(pAscending+largest) = temp;
} // for
}
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
"Getting core dumps"? You mean segmentation faults?
Despite the fact that looking at that code hurts my head... did you make pAscending actually point to anything yet? I don't see it anywhere in the code you provided in the last post so playing around with it while it's empty would give you major errors =P
you're also having a loop in that allows walker to be 1-5, while in all previous loops you've been playing with 0-4... accessing 5 if nothing is there would cause some code explosions too ^^;
<b>edit:</b> yeah, I know there's probably stuff in Main to handle pAscending actually pointing to something, but just incase...
*Edit*
Goodie I now have a D in the course.
*Edit*
Goodie I now have a D in the course. <!--QuoteEnd--> </td></tr></table><div class='postcolor'> <!--QuoteEEnd-->
Sorry to hear that <!--emo&:(--><img src='http://www.unknownworlds.com/forums/html//emoticons/sad.gif' border='0' style='vertical-align:middle' alt='sad.gif' /><!--endemo-->
Is there a textbook? Useful? (Mine wasn't long way back ago.)
Now that the assignment is over, you should really ask ur teacher for the solution. It may help later *cough*finals*cough*.
What I think the assignment requires is the sorting of a list of pointers to ints. You start off with an original array of ints. You then set up an array of pointers, each pointer points to an integer in the value array. This array of pointers is the one to be sorted.
And you're right, pointers are the devil.
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
#include <time.h>
#include <iostream.h>
#include <math.h>
// Prototype Declarations
// Don't declare protos in functions. Nobody in the industry ever does this (you can tell
// your tutor this btw).
// Always put names in protos for all arguments. This makes things clearer to users using
// your functions - even if that person happens to be you
// I never use [] notation in function arguments. The type of an array's object are pointers
// to the first element. So I use pointers to the first element. For example, instead of using int[],
// I'll use int* (in fact, I use objects, classes and pass by reference - but that's not for here).
// generate an array. Set contents of ppAscending and ppDescending to point to array
void generatearray(int* array, int** ppAscending, int** ppDescending);
// sort ppAscending pointers in ascending order.
// note: we don't need to pass array as we've already assigned ppAscending
void sortascend(int** ppAscending);
// sort ppDescending pointers in descending order
// note: we don't need to pass array as we've already assigned ppDescending
void sortdescend(int** ppDescending);
// output contents of arrays
void displayarray(int* array, int** ppAscending, int** ppDescending);
int main (void)
{
// Local Declaration
// the original array. This is on the stack
// note: you've hard-coded the array size to 5 all over the code. In the real world, you
// wouldn't do this. What if we decided we wanted an aray size of 10 ? You'd have to
// go through all the code and change all the 5s to 10s. And one mistyped value and *bang*
int array[5];
// the sorted arrays. These are on the heap. Remember they will will need cleaning when you've done with them.
// this is an array of pointers to integers
int** ppAscending = new int*[5];
// check the allocation
if (ppAscending)
{
int** ppDescending = new int*[5];
// check the allocation
if (ppDescending)
{
// you don't need to pass the address of anything here.
generatearray(array, ppAscending, ppDescending);
sortascend(ppAscending);
sortdescend(ppDescending);
displayarray(array, ppAscending, ppDescending);
// don't forget to clean up stuff we allocated on the heap
// note: we're using delete[] because we used new[]
delete[] ppDescending;
}
delete[] ppAscending;
}
return 0;
}
void generatearray(int* array, int** ppAscending, int** ppDescending)
{
int i = 0;
// I've used time(NULL) here. Go back to using clock() if this doesn't work on your compiler.
srand(time(NULL));
// always block your code. Believe me, it's better
for (i = 0; i < 5; i++)
{
array[i] = (rand()%98+1);
} // for
// copy integer pointers
for (i=0; i < 5; i++)
{
ppAscending[i] = &array[i];
} // for
// copy integer pointers
for (i=0; i < 5; i++)
{
ppDescending[i] = &array[i];
} // for
} // generatearray
// swap int*s
void swap(int** ppLHS, int** ppRHS)
{
int* pValue = (*ppRHS);
(*ppRHS) = (*ppLHS);
(*ppLHS) = pValue;
}
// put the largest int* from i at i
void exchangelargest(int** ppDescending, int from);
void exchangesmallest(int** ppAscending, int from);
void sortdescend(int** ppAscending)
{
int i = 0;
// if I understand you correctly here, you are sorting the array by iterating
// the array and putting the largest value from the array remainder at each iteration
// note: we only need to iterate up to 5 - 1 because the last value will always be the smallest after 5 - 1
// iterations
for (i = 0; i < 4; i++)
{
exchangelargest(ppAscending, i);
}
} // sortdescend
void sortascend(int** ppDescending)
{
int i = 0;
// note: we only need to iterate up to 5 - 1
for (i = 0; i < 4; i++)
{
exchangesmallest(ppDescending, i);
}
} // sortascend
void exchangelargest(int** ppDescending, int from)
{
int** largest = &ppDescending[from];
int i = from + 1;
while (i < 5)
{
if (*ppDescending[i] > **largest)
{
largest = &ppDescending[i];
}
i++;
}
swap(&ppDescending[from], largest);
} // exchangelargest
void exchangesmallest(int** ppAscending, int from)
{
int** smallest = &ppAscending[from];
int i = from + 1;
while (i < 5)
{
if (*ppAscending[i] < **smallest)
{
smallest = &ppAscending[i];
}
i++;
}
swap(&ppAscending[from], smallest);
} // exchangesmallest
void displayarray (int* array, int** ppAscending, int** ppDescending)
{
int i;
// I've used printf here because it works better in my development environment.
printf("Program by A. Friend.\nAscending (ptr)\tOriginal (ptr)\tDescending (ptr)\n");
for (i = 0; i < 5; i++)
{
// I'm also outputting the pointers so you can see where the values in the sorted lists are coming from.
printf("%d (%p)\t%d (%p)\t%d (%p)\n", *ppAscending[i], ppAscending[i], array[i], &array[i], *ppDescending[i], ppDescending[i]);
}
}
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->