简体   繁体   中英

Returning the pointer address of a value within an array

I am required to find the address of a matching value in an array, as stated in the following question:

This function searches length elements of array list for the value target. It returns the index where target was found, or -1 if the value is not present.

 int find(int target, int list[], int length) { for (int i = 0; i < length; ++i) { if (list[i] == target) return i; } return -1; } 

Rewrite the function using pointers to indicate the search range. The search should begin by examining the element at start and end at stop without examining that value. The return value should be a pointer to the location of the target value or a null pointer if the values is not present.

The code I have is here, but I can't seem to get it to work:

#include <cstdlib>
#include <iostream>
using namespace std;

int* find(int target, int* start, int* stop)
{    
    while(start <= stop)
    {
        if (*start == target)
        {
            return start;
        }    
        start++;
    }

    return nullptr;
}

int main()
{
    int someArray[] = {3,10,19,7,3,45,123,4,9,89};

    int start = *someArray[0];
    int stop = *someArray[9];

    cout << *find(19, start, stop);
    return 0;
}

The start and stop pointers should be initialized appropriately:

int* start = &someArray[0];
int* stop = &someArray[9];

You also want to know the index of the array where the target is at (and not the target itself), so you have to change the line:

cout << *find(19, start, stop);

to

cout << find(19, start, stop) - someArray ;

In this way, you will not be in the danger of accessing the nullptr . If a negative value is printed, it would mean that the target is not in someArray .

I would use std::find and std::distance , to get the index of the value.

#include <iostream>
#include <algorithm>

int main() {
    const int someArray [] = {3,10,19,7,3,45,123,4,9,89};
    const int len = sizeof(someArray) / sizeof(int);

    const auto it = std::find(&someArray[0], &someArray[len], 19);

    std::cout << std::distance(&someArray[0], it);
    return 0;
}

or if you use std::array or another std container you can use .begin() and .end() .

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    const std::array<int,10> someArray = {3,10,19,7,3,45,123,4,9,89};     

    const auto it = std::find(someArray.begin(), someArray.end(), 19);

    std::cout << std::distance(someArray.begin(),it);
    return 0;
}

You can use

const auto start = someArray.begin() + value;

and likewise stop to norrow the search area of someArray .

您的函数find()需要数组开始/结束的“地址”,但是您要分配数组开始/结束的“值”。

Your start and stop variables need to be pointers. For example:

int *start = &someArray[0];
int *stop = &someArray[9];

And be careful by using the line

cout << *find(19, start, stop);

with another value that is not in the array. This results in an access violation because you try to derefence a nullptr .

An asterisk (*) dereferences a pointer. That is, it gives you the value at the address. An ampersand (&) gets the pointer to a value. The start and stop pointers should be the addresses of the first and last values.

If you turn on more warnings, the compiler might tell you that you are dereferencing something that is not a pointer and you are passing int values to the function where pointers are expected.

int *start = &someArray[0];
int *stop = &someArray[9];

If you have C++11 (which you should), then std::end is specialized for arrays.

You can avoid either having to hard-code the array size as the magic number 9 , or writing out the sizeof(someArray)/sizeof(someArray[0]) incantation (which is itself at least better than hardcoding the type in your sizeof expression).

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

int main() {
    const int someArray [] = {3,10,19,7,3,45,123,4,9,89};

    const auto it = std::find(std::begin(someArray), std::end(someArray), 19);

    std::cout << std::distance(std::begin(someArray), it);
    return 0;
}

If you do want to use your custom find function, note that begin and end just return pointers in this case anyway, and it will also be a pointer in the code above.

As other answers have stated, your start and stop variables need to be int* pointers, and you need to use the & address operator instead of the * dereference operator to obtain those pointers:

int *start = &someArray[0];
int *stop = &someArray[9];

However, there is another, more subtle, bug in your code. As the documented requirement states:

The search should begin by examining the element at start and end at stop without examining that value .

But your code is examining the value at stop . This is because you are using the <= operator, when you should be using the < operator instead:

//while (start <= stop)
while (start < stop)

Making this change then creates a new bug in your main() code. someArray[9] is the last element in the array (89). After making the above change, this element will no longer be compared when using someArray[9] for the stop pointer. So, if you were to call find(89, start, stop) , it would return nullptr instead of the address of someArray[9] . As such, you need to set stop to the address of someArray[10] instead:

int *stop = &someArray[10];

This is on par with how STL algorithms works with iterator ranges (and raw pointers are also iterators). The ending iterator always represents "1-past-the-end" and is never dereferenced, only used for comparing when the starting iterator reaches the ending iterator. The C++ standard also explicitly allows obtaining a pointer to "1-past-the-end" of an array, for similar reasons.

With that said, try something like this:

#include <iostream>
#include <cstddef>

int* find(int target, int* start, int* stop)
{    
    while (start < stop)
    {
        if (*start == target)
        {
            return start;
        }    
        ++start;
    }

    return nullptr;
}

int main()
{
    int someArray[] = {3,10,19,7,3,45,123,4,9,89};

    int *start = &someArray[0];
    int *stop = &someArray[10];

    std::cout << "Enter a number to find: ";

    int num;
    std::cin >> num;

    int *found = find(num, start, stop);
    if (found)
        std::cout << "Found at index " << static_cast<ptrdiff_t>(found - start);
    else
        std::cout << "Not found";

    return 0;
}

Live Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM