-2

I want to find the lowest element in the array using a function lowest(). But this program does not work. It shows the error

invalid type argument of unary '*' (have 'int')

Here is the code:

#include <stdio.h>

int lowest(int *j, int n) { //For finding the lowest element
    int i, temp, 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
}

int main() {
    int n;
    printf("Enter the number of inputs: ");
    scanf("%d", &n);

    int arr[n], 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 %d.", *low, low); //Error occurs
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • If you want to return the address of the smallest element, your "lowest" function should have return type ``int *``. But it has ``int``. – BitTickler Jan 30 '16 at 08:08
  • 1) `tempAdd = j + i;` You are trying to assign a address to the interger. 2) You have not assigned any value to the temp.So we cant predict what value would be there during first if `if(temp > *(j + i))` – Karthick Jan 30 '16 at 08:13
  • It is unclear whether this is a C or C++ question. Do not tag your question with both tags, as they are separate languages. – Archimaredes Jan 30 '16 at 09:00
  • 1
    @Archimaredes In those cases I switch to "c-ish c++" mode ;) – BitTickler Jan 30 '16 at 09:03
  • Question: Why are there 2 down votes. Agreed the question has no big value for future users of SO. But the question is not lacking in any other aspect imho. So why downvoting? – BitTickler Jan 30 '16 at 20:46
  • @BitTickler No sense asking past downvoters to explain - they've moved on. But typically, a question containing a typo or simple syntactic mistake will tend to be downvoted - precisely because it has no big value for future users. – Mogsdad Jan 31 '16 at 00:15

5 Answers5

1

Your function lowest has problems:

int lowest(int *j, int n) { //For finding the lowest element
    int i, temp, 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
}
  • you forgot the braces around the if block. Indentation does not determine block structure in C.
  • the semantics are inconsistent: you return the index to the lowest element but you set tempAdd to j + i which is a pointer to the lowest element.
  • you do not initialize temp, nor tempAdd. The behavior is undefined.
  • it is confusing to name a pointer j, j is usually designates an integer index. Use p.

Here is a simpler version:

int lowest(int *p, int n) { //For finding the lowest element
    int i, tempAdd = 0;
    for (i = 1; i < n; i++) {
        if (p[i] < p[tempAdd]) {
            tempAdd = i;
        }
    }
    //Return the index of the lowest element
    return tempAdd;
}

In main, you should modify the code because low is not a pointer:

printf("\nThe Lowest element in the list is %d with address %d.",
       arr[low], &arr[low]);
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Failed to notice the missing braces at first. I am a "curlies in front" guy and cannot really read that "curlies in the back" style very well. – BitTickler Jan 30 '16 at 20:42
  • @BitTickler: *braces on their own line* tends to produce a lot more lines of code, which is not very pleasant on StackOverflow as it frequently causes the code panes to scroll. *open brace at the end of commanding statement* was first devised by K&R in their original style (except for function bodies), along with spacing rules. – chqrlie Jan 30 '16 at 21:08
  • Main reason I adopted the curlies in front like 20 years ago and stuck to it ever since is the fact, that there is no room for comments, then. It kind of bugs me, if the comment for the condition statement is suddenly inside the block, if you use brackets at the end. ``if(x < 0) // test for valid argument \n {...}`` would look like ``if(x < 0) { // test for valid argument \n...}`` and it would appear the comment describes what the block does, not the statement. – BitTickler Jan 30 '16 at 21:12
  • @BitTickler: this commenting issue is real for `else if` blocks, but for isolated `if` blocks, you can move the comment above the `if` on a line of its own. – chqrlie Jan 30 '16 at 22:28
0
  • For printing address you can use %p as below.

    printf("\nThe Lowest element in the list is %d with address %p.", low, low);
    
Sagar Patel
  • 864
  • 1
  • 11
  • 22
0

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.

  1. STL- style would be: int * lowest( int *begin, int * end )
  2. 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:

  1. 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.

BitTickler
  • 10,905
  • 5
  • 32
  • 53
0
#include<stdio.h>

int *lowest(int *j, int n) { //For finding the lowest element
   int i, temp;
   int *tempAdd;
   temp=*j;
   tempAdd=j;
   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
}

Along with this correct the following line int low = lowest(arr, n); to int *low = lowest(arr, n);

Karthick
  • 1,010
  • 1
  • 8
  • 24
0

the lowest function should be:

int *lowest(int *j, int n) { //For finding the lowest element
    int i, temp = *j;
    int *tempAdd = NULL;
    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
}

and in your main function: use int *low instead of int low and use %p to display the variable address.

trank
  • 952
  • 11
  • 8
  • 1
    Leaving ``temp`` uninitialized yields undefined behavior. Variables are not default initialized to 0 or some other value. – BitTickler Jan 30 '16 at 08:38
  • oops, my mistake! i run the code under g++ and it doesn't show me any warning. i think in this case `temp` should be `*j`. – trank Jan 30 '16 at 12:21