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 atstop
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;
}
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.