2

I want to find the position of an element in an array, the thing is that when I create the function to return the index of the desired element the if statement does not work. However, if I do it in the main function it works perfectly. I would appreciate if someone could explain me why this is happening.

#include <iostream>
#include <algorithm>
int find_index(double vector, double *value, int size_vector);


int main() {
    double vec_eye_x[2]={2323,1}; // center position x two eyes.
    double vec_eye_y[2]={33,2}; // center position y two eyes.
    int index_val=1;
    double *yc_max=std::max_element(vec_eye_y,vec_eye_y+2); // Creating a pointer
    double *yc_min=std::min_element(vec_eye_y, vec_eye_y+2);
    double *xc_max=std::max_element(vec_eye_x,vec_eye_x+2);
    double *xc_min=std::min_element(vec_eye_x, vec_eye_x+2);

    int index=0;
    for(int i=0; i<2; i++){
        if(*xc_min==vec_eye_x[i]){std::cout<<"Works in the main function"<<std::endl;}
    }
    std::cout << "index val: " <<find_index(vec_eye_x, &xc_max,2)<<std::endl;
    return 0;
}


int find_index(double vector_x, double *value, int size_vector){
    int index=0;
    for(int i=0; i<size_vector; i++){
        if(*value==vector_x[i]){index=i;}
    }
    return index;
}
1
  • Wondering how this would even compile: Your function accepts a single double, but vec_eye_x is an array (which would decay to a pointer). xc_max already is a pointer, &xc_max produces a pointer to pointer (double**). At very least, turn compiler warnings on (-Wall) and listen to! Commented Nov 28, 2019 at 10:45

4 Answers 4

5

Index of that element is simply

std::distance(vec_eye_x, xc_max);

Or if you insist on pointer arithmetic then

xc_max - vec_eye_x;

Note: std::distance is declared in header <iterator>


If you insist on using your original method with iterating over the array again, then the issue with your code was pointed by @Davide Spataro in their answer. Your first argument to find_index is a single double, not an array.

Sign up to request clarification or add additional context in comments.

Comments

2

Aside from the issues mentioned by Davide, you also have an inconsistency problem: in your "main function" test, your are looking for the position of *xc_min; however, the value (to search for) that you pass to find_index is xc_max!

Here's a working version of your code, with changes annotated with triple-slash (///) comments:

#include <iostream>
#include <algorithm>
int find_index(double* vector, double* value, int size_vector); /// NOTE: 1st argument shuld be pointer (array)!

int main() {
    double vec_eye_x[2] = { 2323,1 }; // center position x two eyes.
    double vec_eye_y[2] = { 33,2 }; // center position y two eyes.
    int index_val = 1;
    double* yc_max = std::max_element(vec_eye_y, vec_eye_y + 2); // Creating a pointer
    double* yc_min = std::min_element(vec_eye_y, vec_eye_y + 2);
    double* xc_max = std::max_element(vec_eye_x, vec_eye_x + 2);
    double* xc_min = std::min_element(vec_eye_x, vec_eye_x + 2);

    int index = 0;
    for (int i = 0; i < 2; i++) {
        if (*xc_min == vec_eye_x[i]) { std::cout << "Works in the main function (" << i << ")" << std::endl; }
    }
    std::cout << "index val: " << find_index(vec_eye_x, xc_min, 2) << std::endl;/// Changed "&xc_max" to "xc_min"
    return 0;
}

int find_index(double* vector_x, double* value, int size_vector) { /// NOTE: 1st argument shuld be pointer (array)!
    int index = 0;
    for (int i = 0; i < size_vector; i++) {
        if (*value == vector_x[i]) { index = i; }
    }
    return index;
}

Comments

2

Your code is far away from even compile because for instance:

  • if you want to use vector_x inf find_index as an array, then vector_x needs to be declared as follows: find_index(double* vector_x,.. (with a star).

A working version of your function could be:

int find_index(const double* vector_x, const double value, const int size_vector){
    int index=0;
    for(int i=0; i<size_vector; i++){
        if(value==vector_x[i]){index=i;}
    }
    return index;
}

Also please note that your function returns the last occurrence of value in vector_x. If you just need any index you can speed up your function and return immediately after you find an occurrence.

if(value==vector_x[i]){ return i;}

As a side note, what happens when value is not present in vector_x? You return 0 meaning that you found an occurrence at position 0 which is wrong.

5 Comments

There's little use in const-ness for parameters that are accepted by value...
@Aconcagua Readability improves. Whoever reads the code knows noone that is purely an input.
Depends on point of view. As user of the function, I don't care if the function modifies the input or not if it is a copy anyway. Just forces me to read more, so readability even decreased (well, the function should be documented well, of course, not forcing me to read the implementation that possibly is heavy to understand anyway). There might be some use for those modifying the function. Well, but which will happen more often?
Indeed. point of views. I think code should speak for itself and make the documentation superfluous. If your implementation is heavy and unreadable the problem is not the documentation or an additional const. =)
There's some truth about. On the other hand, you don't always have the code available (e. g. if using some dll or pre-compiled static library), so you rely on documentation... Highly optimised code, possibly even with inline assembly, is often a hard nut to crack, too...
1

The variable vec_eye_x has an array type. However the corresponding parameter in the function find_index has the type double.

Similarly the expression &xc_max has the type double ** but the corresponding function parameter has the type double *.

The function can be declared and defined the following way

size_t find_index( const double *vector, size_t n, double value )
{
    size_t i = 0;

    while ( i < n && vector[i] != value ) ++i;

    return i;
}

And the function can be called like

std::cout << "index val: " <<find_index( vec_eye_x, 2, *xc_max )<<std::endl;

Pay attention to that there is the standard algorithm std::find. You could use it the following way

#include <iterator>
#include <algorithm>

//…

std::cout << "index val: " << std::distance( std::begin( vec_eye_x ),
                                             std::find( std::begin( vec_eye_x ), std::end( vec_eye_x ), *xc_max ) )
          << std::endl;

Here is a demonstrative program

#include <iostream>
#include <iterator>
#include <algorithm>

size_t find_index( const double *vector, size_t n, double value )
{
    size_t i = 0;

    while ( i < n && vector[i] != value ) ++i;

    return i;
}

int main()
{
    const size_t N = 2;
    double vec_eye_x[N]={ 2323, 1 }; // center position x two eyes.
    double vec_eye_y[N] = { 33, 2 }; // center position y two eyes.

    auto yc_max = std::max_element( std::begin( vec_eye_y ), std::end( vec_eye_y ) );
    auto yc_min = std::min_element( std::begin( vec_eye_y ), std::end( vec_eye_y ) );
    auto xc_max = std::max_element( std::begin( vec_eye_x ), std::end( vec_eye_x ) );
    auto xc_min = std::min_element( std::begin( vec_eye_x ), std::end( vec_eye_x ) );

    size_t pos = find_index( vec_eye_x, N, *xc_max );     

    if ( pos != N )
    {        
        std::cout << "index val: " << pos << std::endl;
    }

    auto it = std::find( std::begin( vec_eye_x ), std::end( vec_eye_x ), *xc_max );

    if ( it != std::end( vec_eye_x  ) )
    {
        std::cout << "index val: " << std::distance( std::begin( vec_eye_x ), it ) << std::endl;
    }

    return 0;
}

Its output is

index val: 0
index val: 0

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.