我正在尝试编写一个函数gtk_init(&argc, &argv)
,以便在int数组数据中搜索等于first的元素,然后立即搜索第二个元素。如果发生这种情况,该函数将首先返回指向该元素的指针。如果该情况在数组中发生多次,则指针应指向第一个情况。
我的代码是这样的:
int* findPair(int* data, int numEls, int first, int second)
当我输入两个#include <stdio.h>
int* findPair(int* data, int numEls, int first, int second)
{
int i = 0;
int *n = NULL;
for (i = 0; i < numEls; i++) {
if(data[i] == first && data[i + 1] == second) {
n = &data[i];
}
}
return n;
}
int main()
{
int data[] = {1, 10, 2, 1, 2, 1, 2};
int* p = findPair(data, 7, 1, 2);
if (p != NULL) {
printf("Found at position %zd\n", p - data);
}
else {
puts("Not found");
}
}
进行测试时,它指向第二次出现(位置5而不是位置3)。是否有提示我做错了?
答案 0 :(得分:2)
for
函数中的findPair
循环不会在第一次出现一对时停止。相反,它会继续前进,寻找更多的货币对,并且每遇到一对货币对,它就会覆盖n
。因此n
将始终指向最后一次出现(好,指向最后一次出现的第一个元素)。
找到第一个匹配项后,您需要立即停止for
循环。
使用break
语句从循环中过早退出:
for (i = 0; i < numEls; i++) {
if(data[i] == first && data[i + 1] == second) {
n = &data[i];
break;
}
}
找到第一对后,n
将被设置为指向该对的第一个元素,并且循环将立即退出,跳转到函数的return
语句。
答案 1 :(得分:2)
是的,您的循环总是在数组中找到最右边的一对。看,如果找到匹配项,循环仍然继续,以后再重新分配n指向其他元素。
此外,如果您在数组中再添加一个元素:
int data[] = {1, 10, 2, 1, 2, 1, 2, 1};
int* p = findPair(data, 8, 1, 2);
行为将变得不确定(您的程序可能会出现段错误)
因此,传递数组的长度减去1即可起作用,或者更好的方法是,正确终止循环:
for (i = 0; i < numEls - 1; i++) {
if(data[i] == first && data[i + 1] == second) {
n = &data[i];
break;
}
}
作为额外的小优化,您可以在某些情况下避免进行额外的比较:
if(first != second) {
for (i = 0; i < numEls - 1; ++i) {
if(data[i + 1] == second) {
if(data[i] == first) {
n = &data[i];
break;
}
else ++i;
}
}
return n;
}
for (i = 0; i < numEls - 1; ++i) {
if(data[i + 1] == first) {
if(data[i] == first) {
n = &data[i];
break;
}
}
else ++i;
}
return n;