Here the first iteration of a fixed function. It still is not 100% as I would write it but restricts itself to address the problem of the question.
As you want to return the address, I adjusted the return type as well as the type of variable tempAdd
int* lowest(int *j, int n) { //For finding the lowest element
int i, temp;
int *tempAdd;
for(i = 0; i < n; i++) {
if(temp > *(j + i)) {
temp = *(j + i);
tempAdd = j + i;
}
}
return tempAdd; //Sends the address of the lowest element
}
E.g., for parameter n = 0
the return value of your function would be undefined if no further changes to the function are made.
As variable temp
is also not initially initialized, it is also possible that the address returned is undefined in case, that no member of the array is smaller than the (random) value of variable temp
.
Here, a slightly more robust version:
int* lowest(int *j, int n) { //For finding the lowest element
if( 0 == n ) return NULL; // empty arrays have no smallest element!
int i;
int temp = j[0]; // instead of using pointer arithmetic you can also use this syntax.
int *tempAdd = j; // initially the first element is allegedly the smallest...
for(i = 1; i < n; i++) // loop starts at index 1 now!
{
if(temp > *(j + i)) {
temp = *(j + i);
tempAdd = j + i;
}
}
return tempAdd; //Sends the address of the lowest element
}
Your function main()
also has its issues. You cannot create an automatic (stack-located) array of dynamic size, which is what you try. Instead, if you want to query the user for the size of the array, you would have to resort to a heap-based array, instead. Or you would query for a size, which is smaller or equal an arbitrary chosen fixed size of your stack based array.
int main() {
int n = 0;
printf("Enter the number of inputs (1..500): ");
scanf("%d", &n);
if( n < 1 || n > 500 ) {
puts("Invalid input.");
return -1;
}
int arr[500]; // 500 was chosen because most likely no one is crazy enough to manually type in more values by hand ;)
int i;
for(i = 0; i < n; i++) {
printf("\nEnter element no. %d: ", i + 1);
scanf("%d", &arr[i]);
}
for(i = 0; i < n; i++) {
printf("Element no. %d is %d with the address %d.\n", i + 1, *(arr + i), arr + i);
}
int * low = lowest(arr, n); //Saves the address of the lowest element.
printf("\nThe Lowest element in the list is %d with address %p.", *low, low); //Error occurs
return 0;
}
Also changed the formatting to "%p" for pointer.
Also changed type of low
from int
to int *
.
Last not least you would have to change main()
further, if you were to allow 0 array size. Why? Because in your printf you write ...,*low,...
. As lowest() would return NULL in the case of n = 0
, you would dereference a NULL pointer, which leads to a nasty run time error.
From a design perspective, eventually, returning the address in lowest() appears to break the level of abstraction, related to the fact that you pass in the length of the array. You mix two styles, basically.
- STL- style would be:
int * lowest( int *begin, int * end )
- Vintage- style would be:
int lowestIndex( int *arr, int n)
The second version, though would have the problem that you cannot express a "no result" outcome. E.g if Array size is 0 or other invalid arguments are being passed to the function. Thus, often people would do it this way instead:
bool lowestIndex( int * arr, int n, int *result )
... where the return value indicates success and the result content is only valid if the return value was true
.