-3

I have been trying to figure this out all day and cannot seem to make it work. Why does my binary search work if I input the array length in manually but when I swap the manual input for:

int max = sizeof(list)/sizeof(list[0]);

it doesn't seem to work. For instance if I try to search for a 2 in a 11 element array of 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 it can't find 2. But if I change int min = 11. It can find 2. Here is the function binary sort:

int binarysearch(int *list, int sfor)

    int min = 0;
    int max = 10; 
    int mid = (min + max)/2;

    while(min <= max)
    {
        if (sfor == list[mid])
        {
            printf("The number you are searching for is in %i place \n", mid + 1);
            return 0;
        }
        else if (sfor < list[mid])
        {
            max = mid - 1;
        }
        else
        {
            min = mid + 1;
        }

        mid = (min + max)/2;
    }

        printf("Could not find number! \n");
        return 1;



int main(int argc, string argv[]) // number searching for is passed through 
{                                 // command line argument

    printf("How many numbers did you want to search through? \n");
    int a = GetInt(); //int a is how big should the array of numbers be
    printf("What are they: \n");

    int i = 0;
    int b[a];

    for (i = 0; i < a; i++)
    {
        b[i] = GetInt(); //cycles though each int of the array
    }

    int x = atoi(argv[1]); //converts command line argument to an int

    binarysearch(b, x);
}

Will greatly appreciate any help.

user3386109
  • 34,287
  • 7
  • 49
  • 68
  • 2
    How is `list` defined? `int * list;`? – Sourav Ghosh May 09 '16 at 20:24
  • Learn to debug your code. Print the value of min and check if it is correct or not. – user31264 May 09 '16 at 20:27
  • When I debug my code it says max = 2 but if the array length is 11 how does int max = sizeof(list)/sizeof(list[0]); get 2? – Sebastian Bunney May 09 '16 at 20:35
  • Also learn to minimize your question. Your problem had *nothing* to do with binary search. It should have said "sizeof not working for array parameter" or something like that. The posted function should have done nothing more than print the size. It would have literally taken seconds to reduce the problem to that before posting. Show *some* effort. – Tom Karzes May 09 '16 at 20:38
  • [Another duplicate](https://stackoverflow.com/questions/1975128/sizeof-an-array-in-the-c-programming-language). – user3386109 May 09 '16 at 20:38

1 Answers1

0

Your problem is here:

int min = sizeof(list)/sizeof(list[0]); 

That will not work for arrays passed to functions (as you cannot actually pass an array to a function). You must also pass the size of the array.

bodangly
  • 2,473
  • 17
  • 28
  • This is no "trick", but a normal and legal expression. And the reason it does not work is because you cannot pass an array to a function in C. The last sentence is just wrong. – too honest for this site May 09 '16 at 20:46
  • @Olaf How is it wrong? It will not work if you declare an array in one spot and then pass it off to another function, because as you state you cannot actually do that. Furthermore, it only works when their size is known at compile time as sizeof is not a function but a macro. – bodangly May 09 '16 at 20:49
  • @Olaf I edited my response to be more clear and removed the word trick (though I maintain it is not recommended to do so in any case. You should always know the size of your array, whether you allocated it at run time or compile time, that size should be captured somewhere. You should never have to resort to this method, and I would go as far as to say it is a code smell.) – bodangly May 09 '16 at 20:52
  • Actually, `sizeof` is a keyword. The issue is that when an array is passed to a function, it decays to a pointer. So when `sizeof` is applied to the function argument, it returns the size of a pointer. – user3386109 May 09 '16 at 20:52
  • @user3386109 Sizeof is still implemented by the compiler, not evaluated at run time. It is technically an operator if we are being language lawyers. – bodangly May 09 '16 at 20:53
  • It is a normal construct. E.g. the Linux Kernel uses a macro for that `length_of`. That has nothing to do with translation units and very well works for dynamic arrays, too: `int (*a)[10]; sizeof(*a)`. Sorry to tell, but the edit is not better than the original. – too honest for this site May 09 '16 at 20:54
  • @Olaf Sizeof is not a run time function, it is evaluated by the compiler. It does not work the way you are thinking... You cannot use it to get the size of an array not known at compile time. – bodangly May 09 '16 at 20:56
  • @bodangly Fair enough, it's a *keyword* that's used as an *operator*. So we agree that it is definitely *not* a macro. But you ignored the more important point. The problem has nothing to do with how `sizeof` is implemented, or when it's evaluated. It has everything to do with the fact that an array decays to a pointer when it's passed to a function. – user3386109 May 09 '16 at 20:57
  • @bodangly: That is not exactly correct. For a VLA the length very well is evaluated at run-time. – too honest for this site May 09 '16 at 20:57
  • @user3386109: It is gramatically an operator (keyword is a term of the lexer, not the grammar, at that level `+` or `if` are all keywords, although named differently for part historical reasons and part of grouping in the lexer) exactly like `++` or `&` (prefix semantics). – too honest for this site May 09 '16 at 20:59
  • @Olaf See section 6.4.1 which contains a list of keywords, including `sizeof`. – user3386109 May 09 '16 at 21:02
  • 1
    I removed the contentious line. My understanding of sizeof is outdated apparently. If it is used on a VLA a modern compiler will support it by emitting code to get the length. – bodangly May 09 '16 at 21:03
  • @user3386109: See the title of `6.4` which clearly is "**lexical** elementes". That's exactly what I wrote. But that does not mean it is not an operator. See 6.5.3 ("Unary **operators**"). – too honest for this site May 09 '16 at 21:04
  • @bodangly: Well, it has no choice (poor compiler). May that's why MSVC does not keep up with the standard ... – too honest for this site May 09 '16 at 21:05
  • @Olaf That's exactly what I wrote: *"it's a keyword that's used as an operator"* – user3386109 May 09 '16 at 21:08
  • @user3386109: It is not! It is not "used as an operator", but it **is** an operator. The first implies it can also be used otherwise. You confuse two different levels of source code analysis: the lexical analysys (i.e. tokenising the input, syntactical analysis) and the parser (checking the grammar, semantical analysis). Anyway, that is not even close to the major issues of that answer. – too honest for this site May 09 '16 at 21:11
  • Nope, the first does *not* imply that it can also be used otherwise. It implies that not all keywords are used as operators. This particular keyword, the `sizeof` keyword, *is* used as an operator. – user3386109 May 09 '16 at 21:14