在C中:将数组与字符串和整数元素进行比较

时间:2016-02-16 22:06:22

标签: c arrays

在C中:我编写了一个函数,用于检查类型为arr2的子数组int是否存在于数组arr1中的“原样”类型。如果arr2的所有元素都以完全相同的顺序在arr1中找到,则返回1,否则返回0。功能似乎工作正常,但我有两个问题:

Q1 :如果我们想对两个数组中的混合类型的元素做同样的事情,特别是如果我们事先不知道将使用哪些类型的元素以及以什么顺序?我的意思是每个元素的类型和它们的外观顺序都必须由用户自行决定。我已经阅读了很多类似的Q& A但我仍然不清楚解决方案。

Q2 :请考虑以下示例:

int arr1[] = {34, 231, "not the declared type..", "..recognized nevertheless", 3, 7};

int arr2[] = {231, "not the declared type..", "..recognized nevertheless"};

为什么我的功能实际工作(例如在上述情况下返回1)?我认为它应该失败 - 因为使用的元素不是声明的类型(int) - 或者更糟糕的是我会得到编译器错误。相反,它似乎成功,因为它甚至可以恰当地识别和比较最后一个句号或大写字母。好吧,它确实失败了浮点数(我猜它将它们转换为整数并只比较整数部分?)但为什么它在其他情况下没有问题呢?它是否也会转换字符串,以及发生何种转换?

我对C和论坛都很陌生,所以请原谅无知。

3 个答案:

答案 0 :(得分:5)

c中的数组是同源,也就是说,所有元素都是相同的类型。您描述的示例:

int arr1[] = {34, 231, "not the declared type..", "..recognized nevertheless", 3, 7};

是无效代码。初始值设定项必须全部为int,(或表达式可隐式转换为int)。

如果您的编译器没有为此代码生成诊断消息,那么您需要调高编译器的警告级别。

某些编译器可能会将字符串转换为表示字符串第一个字符的内存地址的整数,作为非标准扩展名。但C标准表示他们必须在这样做时输出诊断信息。

答案 1 :(得分:0)

  

为什么我的功能确实有效?

诀窍是,在C中,你可以这样做,但结果肯定不能可靠地满足OP的需求。

int arr1[] = {34, 231, "not the declared type..", "..recognized nevertheless", 3, 7};

int arr2[] = {231, "not the declared type..", "..recognized nevertheless"};

作为int数组的列表初始值设定项,每个字符串文字(如"not the declared type..")都会转换为第一个元素的地址:char *。由于数组需要int,因此会发生char *int转换,这会产生警告。技术上允许,但不推荐。将char *转换为int本身就是一个问题。极少数情况下指向整数转换的指针有一定意义,它应该""转换为void *,然后转换为intptr_t类型的可选支持的特殊大小的整数。该整数类型足够宽,可以往返于有效指针。 int可能不够广泛。

转换为int可能会丢失信息,因此结果现在可能是指针的哈希码(例如,其最低32位)。即使是相同内容的两个字符串文字也可能会或可能不会转换为与可能存在或不存在于同一位置的int相同的int。两个字符串文字可能会转换为相同的sh start-spark-shell.sh Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/launcher/Main Caused by: java.lang.ClassNotFoundException: org.apache.spark.launcher.Main at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) Could not find the main class: org.apache.spark.launcher.Main. Program will exit. ,但具有不同的内容 - 哈希冲突。事情似乎有效 - 但不是便携/可靠。

故事时间结束:C允许OP很多绳索,绰绰有余地挂起程序。这里没有安全网。

答案 2 :(得分:0)

我想我找到了我的第二个问题的答案,它确实是(规避)调试器:为了阻止控制台窗口关闭,我继续使用Control + F5快捷方式,我现在意识到它运行没有调试器的应用程序。我只是尝试使用F5并且有错误(无论如何对我都没有帮助)尽管程序仍然成功运行。但是我仍然不知道这是怎么回事。我认为只有两种情况:语言中的语法是正确的还是不正确的。这显然是不正确的。为什么它的成功与它一起成功?

我的第一个问题仍然有效。感谢。