在C中定义的数组在哪里,当我将它作为函数参数传递时,为什么不必再次定义它?

我写了一个C程序,告诉我长度,最低和最高的ANSI字符。 有一点我不明白,为什么我必须在main函数中声明cString,而不是sString?

#include #define LENGTH 64 int stringstats(char sString[], char* cHighest, char* cLowest) { int iLength = 0; int i = 0; *cLowest = sString[0]; *cHighest = sString[0]; while(sString[iLength] != '\0') { iLength++; } for(i = 0; i <= iLength-1; i++) { if(sString[i]  *cHighest) *cHighest = sString[i]; } return iLength; } int main(void) { char cString[LENGTH] = {0}; int iLength = 0; char cHighest = 0; char cLowest = 0; while(1) { printf("input String ('q') to exit) \n"); scanf("%62s", cString); if(cString[0] == 'q') break; iLength = stringstats(cString, &cHighest, &cLowest); printf("Length = %i \n", iLength); printf("Lowest Character = %c \n", cLowest); printf("Highest Character = %c \n\n", cHighest); } return 0; } 

C字符串中的基本字符是字符数组。 为了非常技术性,它们应该以空字符’\ 0’终止,以便与cstd string lib,string.h一起使用。

那么arrays是什么? 它是一个连续的元素块,所有元素都具有相同的类型。 您可以将数组表示法视为另一种forms的指针表示法来访问连续的内存块**。

x = array[0]x = *array真的相同,而x = array[5]x = *(array+5)真的相同

当您在C中传递一个数组作为函数参数时,您实际上只是将指针传递给字符数组的头部。 你的代码可以很容易

 int stringstats(char * sString, ... ) 

所以回答你的问题:

为什么我必须在main函数中声明cString,而不是sString?

你的数组在main() 定义 – 它就在内存中。 它在堆栈上分配,其范围仅限于main() 。 你不需要在stringstats() 声明它,也不是。 但是,当您传递指向sString的指针时,您引用了该数组。 在这样做时,您实际上定义了一个指向堆栈上数组的指针 – 另一个自动变量,其范围仅限于stringstats()

如果cString是与main()在同一文件中的全局变量,而stringstats()在另一个文件中,则可以通过extern在stringsstats stringstats() 声明 cString。 这与定义 cString不同,因为您不会为它分配新的存储空间。

这是一个相关的post: C指针表示法与数组表示法相比:传递给函数时

**它们几乎是一样的,但我想指出一个警告。 在C中有一种称为数组类型的东西。 因为sizeof() (在编译时运行)可以给你整个数组的大小。 但是当你传递这个数组时,它会“衰减”到一个指针,即使你用一个大小传递它,例如foo(array[x]) 。 x实际上没用。 sizeof()现在只是给你你指向的元素的大小。

我喜欢尼克的答案,但它掩盖了一些物品。

从根本上说,C语言中的字符串是八位长的字符数组,您可能需要一个或多个字符才能获得可以绘制到屏幕上的内容,称为字形。

所以当你看到字母’a’时,你真的看到了一个字形 ,它可能存储在一个,两个,三个或四个字符中。 (在这种情况下,它存储在一个字符中,但通常取决于它)。

对于数字范围为0-127的字符,使用1“C-char”到1“字形”是非常安全的,这大致是人们认为的“1字符”; 但是,当你进入128及以上时,你需要知道你正在遵循哪组规则(字符集),或者你可能在逻辑中发现错误,因为你的逻辑不遵循你的字符集字符编码

例如,如果’a’占用了两个’C字符’,那么如果您编写了一个简单的例程来获取长度,则可能需要根据需要返回1或2