9

I want to retrieve the index in the array where the value is stored. I know the value of the item at that point in the array. I'm thinking it's similar to the findIndex function in c#. For example, array[2] = {4, 7, 8}. I know the value is 7, how do I get the value of the index, 1, if I know it is at array[1]?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
user1798299
  • 173
  • 2
  • 4
  • 12

3 Answers3

11

For example you can define the corresponding function the following way

size_t FindIndex( const int a[], size_t size, int value )
{
    size_t index = 0;

    while ( index < size && a[index] != value ) ++index;

    return ( index == size ? -1 : index );
}

Also instead of type size_t you can use type int.

But the better way is to use standard algorithm std::find or std::find_if declared in header <algorithm> provided that you use C++

For example

#include <algorithm>
#include <iterator>

int main()
{
    int a[] = { 4, 7, 8 };

    auto it = std::find( std::begin( a ), std::end( a ), 7 );

    if ( it != std::end( a ) )
    {
        std::cout << "The index of the element with value 7 is " 
                  << std::distance( std::begin( a ), it )
                  << std::endl;
    }
} 

The output is

The index of the element with value 7 is 1

Otherwise you have to write the function yourself as I showed abve.:)

If the array is sorted you can use standard C function bsearch declared in header <stdlib.h>

For example

#include <stdio.h>
#include <stdlib.h>


int cmp( const void *lhs, const void *rhs )
{
    if ( *( const int * )lhs < *( const int * )rhs ) return -1;
    else if ( *( const int * )rhs < *( const int * )lhs ) return 1;
    else return 0;
}

int main() 
{
    int a[] = { 4, 7, 8 };

    int x = 7;
    int *p  = ( int * )bsearch( &x, a, 3, sizeof( int ), cmp );

    if ( p != NULL ) printf( "%d\n", p - a );

    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • In your first example, you have return type of `size_t`. This is `typedef unsigned int size_t;`, so returning a -1 may be problematic. Your second example looks like C++. (tagged C) – ryyker Jul 28 '14 at 20:56
  • @ryyker There is no any problem. Such a way std::string::npos is defined in C++.:) – Vlad from Moscow Jul 28 '14 at 20:57
  • 3
    OP is tagged C, not C++ though. Other than that I like both approaches, except size_t cannot be negative. – ryyker Jul 28 '14 at 20:59
  • 1
    @ryyker IIRC `-1` is implicitly converted to `size_t`, which is the same as `SIZE_MAX` (since overflow/underflow for unsigned integers is not UB) – Drew McGowen Jul 28 '14 at 21:00
  • @ryyker You are right that size_t can not be negative. As for all other you are wrong. -1 assigned to an object of size_t will give the maximum value of size_t. It is not important whether you deal with C or C++. – Vlad from Moscow Jul 28 '14 at 21:00
  • 2
    @VladfromMoscow given that the question is tagged as C, then while a C++ answer is demonstrative, it cannot be used as C code. – Drew McGowen Jul 28 '14 at 21:01
  • @Drew McGowen The more you know the better. – Vlad from Moscow Jul 28 '14 at 21:02
  • 1
    @VladfromMoscow true, but it's irrelevant to this particular question. – Drew McGowen Jul 28 '14 at 21:03
  • Thanks both Vlad and Drew, regarding comment on range of size_t. I am not sure what other assertions I made that are incorrect. The one about the OP being C is correct (unless an edit has been made my OP) – ryyker Jul 28 '14 at 21:08
  • @Drew McGowen I am sure you are mistaken. – Vlad from Moscow Jul 28 '14 at 21:10
  • _It is not important whether you deal with C or C++_. disagree. There are many places (eg. some embedded systems) that do not allow C++ where C methodology is required. Honoring the tag of the OP is usually a good idea for that reason alone. – ryyker Jul 28 '14 at 21:17
  • @ryyker We are not discussing "many places". We are saying that this code is valid in C and as in C++. The problem that you simply do not know this. – Vlad from Moscow Jul 28 '14 at 21:24
  • @VladfromMoscow - really not a big issue for me. I am not arguing the veracity of syntax in your answer(s), all good. And I even learned something about `size_t`. ***Just saying*** OP is for C, not C++. And `std::end( a )` (et. al.) is (are) not valid in C. :) – ryyker Jul 28 '14 at 21:55
2

First its important that the argument list contain size information for the array, i.e. passing a pointer to an array only does not provide enough information to know how many elements the array has. The argument decays into a pointer type with no size information to the function.

So given that, you could do something like this:

int findIndex(int *array, size_t size, int target) 
{
    int i=0;
    while((i<size) && (array[i] != target)) i++;

    return (i<size) ? (i) : (-1);
}

For small arrays this approach will be fine. For very large arrays, some sorting and a binary search would improve performance

ryyker
  • 22,849
  • 3
  • 43
  • 87
1

Here's my version without a additional variable.

// Return index of element starting
// Return -1 if element is not present
int indexOf(const int elm, const int *ar, int ar_cnt)
{
    // decreasing array count till it reaches negative
    // arr_cnt - 1 to 0
    while (ar_cnt--)
    {
        // Return array index if current element equals provided element
        if (ar[ar_cnt] == elm)
            return ar_cnt;
    }

    // Element not present
    return -1; // Should never reaches this point
}

Hope the comments are self explanatory!

Daniel Selvan
  • 959
  • 10
  • 23