我正在读一本教科书,其中一个例子就是这样做的.下面,我以缩写形式复制了这个例子:
#include <stdio.h>
#define SIZE 100
size_t linearSearch(const int array[], int searchVal, size_t size);
int main(void)
{
int myArray[SIZE];
int mySearchVal;
size_t returnValue;
// populate array with data & prompt user for the search value
// call linear search function
returnValue = linearSearch(myArray, mySearchVal, SIZE);
if (returnValue != -1)
puts("Value Found");
else
puts("Value Not Found");
}
size_t linearSearch(const int array[], int key, size_t size)
{
for (size_t i = 0; i < size; i++) {
if (key == array[i])
return i;
}
return -1;
}
Run Code Online (Sandbox Code Playgroud)
这有什么潜在的问题吗?我知道size_t被定义为无符号整数类型,所以如果我返回-1作为size_t返回值,似乎这可能会在某些时候遇到麻烦.
您的编译器可能会决定抱怨比较有符号与无符号 \xe2\x80\x94 GCC 或 Clang 如果激发* \xe2\x80\x94 但否则“它有效”。在补码机器上(现在大多数机器),确实(size_t)-1与 \xe2\x80\x94 相同SIZE_MAX,正如评论中的扩展所讨论的,它对于补码或符号大小是相同的机,因为 C99 和 C11 标准的 \xc2\xa76.3.1.3 中的措辞)。
使用(size_t)-1来指示“未找到”意味着您无法区分最大可能数组中的最后一个条目和“未找到”,但这很少是实际问题。
\n\n\n那么,这只是我最终可能遇到问题的一种边缘情况?
\n
不过,该数组必须是 的数组char,足够大才能引起麻烦 \xe2\x80\x94,虽然 32 位计算机可以拥有 4 GiB 内存,但拥有所有这些内存是相当难以置信的内存致力于字符数组(对于 64 位机器来说,这不太可能成为问题;大多数机器不会运行到 16 艾字节内存)。所以这不是一个实际的边缘情况。
在 POSIX 中,有一种ssize_t类型,即与 的大小相同的有符号类型size_t。您可以考虑使用它来代替size_t. (size_t)-1然而,根据我的经验,它会引起同样的焦虑。另外,在 32 位计算机上,您可以将 3 GiB 内存块视为 的数组char,但作为ssize_t返回类型,您无法使用超过 2 GiB \xe2\x80\x94 的内存,否则您\需要使用SSIZE_MIN(如果它存在;我不确定它是否存在)而不是作为-1信号值。
* \nGCC 或 Clang 必须受到相当大的刺激。仅仅使用-Wall是不够的;它需要-Wextra(或特定-Wsign-compare选项)来触发警告。因为我经常编译-Wextra,因此我意识到了这个问题;并不是每个人都那么警惕。
比较有符号和无符号数量是由标准完全定义的,但可能会导致违反直觉的结果(因为小负数在转换为无符号值时显得非常大),这就是为什么编译器在要求这样做时会抱怨的原因。
\n