几周前我开始学习编程语言 C。我了解 Web 技术,如 HMTL/CSS、Javscript、PHP 和基本的服务器管理,但 C 使我感到困惑。据我了解,C 语言没有字符串数据类型,只有字符数据类型,但我可能错了。
我听说有两种声明字符串的方法。声明字符串的这两行有什么区别:
a.) char stringName[];
b.) char *stringName;
我知道 char stringName[];
是一个字符数组。但是,第二行让我感到困惑。据我了解,第二行创建了一个指针变量。指针变量不是应该是另一个变量的内存地址吗?
在C语言中,一个“字符串”,如你所说,就是一个char
的数组。 C 规范中内置的大多数字符串函数都期望字符串“NUL 终止”,这意味着字符串的最后一个 char
是 0
。不是表示数字零的代码,而是 0
的实际值。
例如,如果您的平台使用 ASCII,那么下面的“字符串”就是“ABC”:
char myString[4] = {65, 66, 67, 0};
当您使用 char varName[] = "foo"
语法时,您是在堆栈上分配字符串(或者如果它在全局空间中,您是在全局分配它,但是不是动态的。)
与您可能使用过的许多其他语言相比,C 中的内存管理更加手动。特别是,有一个“指针”的概念。
char *myString = "ABC"; /* Points to a string somewhere in memory, the compiler puts somewhere. */
现在,char *
是“指向 char 或 char 数组的地址”。请注意该语句中的“或”,对于程序员来说,了解情况很重要。
确保您执行的任何字符串操作不超过您分配给指针的内存量也很重要。
char myString[5];
strcpy(myString, "12345"); /* copy "12345" into myString.
* On no! I've forgot space for my nul terminator and
* have overwritten some memory I don't own. */
“12345”实际上是 6 个字符长(不要忘记末尾的 0
),但我只保留了 5 个字符。这就是所谓的“缓冲区溢出”,是许多严重错误的原因。
“[]”和“*”之间的另一个区别是前者正在创建一个数组(如您所猜)。另一个不保留任何空间(除了用于保存指针本身的空间。)这意味着除非您将它指向某个您知道有效的地方,否则不应使用指针的值进行读取或写入。
另外一点(评论里有人提出的)
您不能将数组作为参数传递给 C 中的函数。当您尝试时,它会自动转换为指针。这就是为什么我们传递指向字符串的指针而不是字符串本身