C programming index number confusion
C programming / selection sort / index number confusion
The below code uses functions to create a selection sort. It's source is http://www.sanfoundry.com/c-program-...ing-functions/ Code:
/* Just think what 'j<=size' implies. if you have a 5 element array, e.g. int b[5], then int b[5] declares (as integer) the array b[] which is comprised of b[0], b[1], b[2], b[3] and finally b[4]. THERE IS NO b[size]!!!!! I even wrote another program where I enter in the elements of an array, then I enter in the element number. Enter in a '0' and you get back the 1st element(NOT the 0th element). Enter in a 2 and an array will give you back the 3rd element. For a array of size 5 (int array[5]), enter in a five, and then you're in trouble, the computer will produce an erroneous number. This is simple to see, but here the above program for some reason defies all c programming logic and states "for(j=1;j<=size...", which implies to retrieve the element n+1 in an array of size n. Does anyone know why j<=size makes the program work yet when I edit the program to "j<size" the program doesn't sort correctly? |
> Specifically, why does "int findmax(int b[],int size)" specify 'j' in "for(j=1;j<=size;j++)"?
> Just think what 'j<=size' implies. It doesn't implies that, because 'size' isn't the size, it's the 'highest index'. You'd better use clearer variable names, eg: Code:
//Function to find the maximum value |
The reason it works is that it starts at size-1
Code:
for(j=size-1;j>0;j--) |
I would not say this code works. In some cases probably it produces the required result, but in some cases that code will simply die.
size means the number of elements in the array, and the index is running from 0 to size-1. Therefore the for loop should be: Code:
for(j=0;j<size;j++) Code:
//Function to find the maximum value |
The key to the answer is that C doesn't care what a variable's name means. It only cares what a variable's usage means.
In swap() we have a variable named "size" and the way it is used, it actually is the size. But in findmax() we have another variable named "size" but based on the way it is used, it should have been named "last". In each pass through the loop in swap() the number passed to findmax() is the index of the last unsorted position. It is not the size of the unsorted portion. It is one less than the size of the unsorted portion. Bad variable names are very confusing to anyone who tries to read the code. So even though the code works, the author should be ashamed. Quote:
Quote:
As an example used to teach C programming, it is terrible for several reasons. But not because it is a poor sorting algorithm. Selecting best algorithms probably should not be part of early teaching of C. Best algorithm is largely a distraction from learning the basics of competent coding. Using meaningful, rather than misleading, variable names should be part of teaching C coding from the start. Expressing ranges as first,limit in most cases and first,size in others and almost never as first,last is an important aspect of decent C style, that should be learned at first by example and rote, because using first,last for a range (or using last alone when first is implied) is a very bad practice whose flaws will not be explainable to beginners nor matter in trivial examples. But if you are in the habit of using last (rather than size or limit) to end a range, by the time you reach serious work where that habit creates a mess, it will be too late to change. Using int rather than unsigned for inherently non negative quantities is another bad habit, best avoided from the start. Quote:
I see that as a badly misnamed variable. "size" in that function is not a size. You see the variable name as a contract, which is then violated by both the function itself and its caller. |
Thanks everyone, Core problem solved!
Thanks to all, I was indeed mislead by the example's use certain misleading words used as variables. More specifically the formal function definition for int findmax(int b, size), the "size" variable mixed me up. I thought the variable going into this function was "size". Actually the variable going into the function findmax was "j" from the swap function's "j" variable, which as all know so well from the previous line of code is "for(j=size-1;j>0;j--)" thus this variable only ranges from size-1 to 1, thus a span falling short of the array's size by 1 element! Naturally then Sanfoundry had written "j<=size" in findmax function's "for(j=1;j<=size;j++)" statement, and not "j<size".
I should have some more time tomorrow evening to look some more at johnsfine and pan64 at more detail to enable me to make the program even better for pedagogical purposes, but the core question has most certainly been solved. Thanks everyone so much!:D |
johnsfine,
Thanks so much for your pointers, and the final program is as below. Code:
/* |
Quote:
|
I don't think changing the name of "size" in swap() to "limit" was helpful. As the size of the unsorted portion, I think the name "size" was just as meaningful as "limit".
I'm less happy with changing the name of "size" in findmax() to "si". That does get rid of the agressively wrong name. But what does "si" mean? If you keep the bad design in which the variable represents a last index, you should make that clearer by naming it "last". Passing a "last" index in C is bad practice, but naming it unclearly makes that worse, not better. The better choice is to change the code to not pass a last index: Code:
/* Quote:
BTW, I think using unsigned instead of int is good practice when quantities are inherently unsigned. But it does require some extra care. One of your comments about >=0 implied you had missed that detail. This program did not need any >=0 checks on unsigned loops. But that need is quite common, and becomes and extra detail to worry about when using unsigned. I think it is worth it, but others likely disagree: The following is a very common loop: Code:
for (i=size-1; i>=0; i--) I code that loop in a lot of serious functions, where the flaws of using int instead of unsigned matter, so I use a form that probably looks strange the first time: Code:
for (i = size; i-- > 0; ) |
Quote:
1) Why doesn't the code "i = size;" include 'size'? 2) The above code works well in the swap function, but when I adapt it for the findmax function and write 'for(m = 1; m-->s; )' I get the following result: Code:
Enter the array's size: 5 |
Each of your questions implies you are failing to see the basic operation i-- in that less usual context.
i-- is a basic C operation, saying to decrement i, but use the value before decrementing for the current expression. So in: for (i = size; i-- > 0; ) { body } in each iteration, the value of i before it is decremented is compared to zero, but the value of i after it is decremented is used within body. Quote:
Quote:
Quote:
So the only good usage of that syntax is as you said: for unsigned index numbers approaching 0(as to avoid testing a negative value that can't inherently exist) |
Quote:
|
All times are GMT -5. The time now is 11:57 AM. |