我想知道为什么会这样。我渴望了解更多关于低级语言的知识,但我只掌握了C语言的基础,就已经让我感到困惑了。
像PHP这样的语言在它们被解释和/或解析时会自动将字符串置为空吗?
我想知道为什么会这样。我渴望了解更多关于低级语言的知识,但我只掌握了C语言的基础,就已经让我感到困惑了。
像PHP这样的语言在它们被解释和/或解析时会自动将字符串置为空吗?
摘自乔尔的博客文章:
记得C语言中字符串是由一系列字节组成,尾部紧跟一个值为0的空字符。这带来了两个明显的影响:
无法知道字符串何时结束(即字符串长度)除非遍历整个字符串查找末尾的空字符。 字符串中不能包含任何值为0的字节,因此无法像存储JPEG图片这样任意储存二进制数据。 C语言字符串为什么会使用这种方法?这是因为在PDP-7微处理器上,UNIX操作系统和C语言被发明时,使用了ASCIZ字符串类型。ASCIZ代表"以0(零)结尾的ASCII码字符串"
存储字符串的方式只有这一种吗?事实上,这是一种最糟糕的字符串存储方法之一。对于复杂程序、API、操作系统、类库等,建议不要使用ASCIZ字符串。
想一想内存是什么:一块连续的字节单元,可以填充任何二进制模式。
2a c6 90 f6
一个字符只是其中一种比特模式。它作为字符串的含义由您处理它的方式决定。如果您使用整数视图(或其他类型)查看相同的内存部分,则会得到不同的值。
如果您有一个变量,它是指向内存中一堆字符开头的指针,您必须知道该字符串何时结束以及下一段数据(或垃圾)何时开始。
让我们来看看这个字符串在内存中的情况...
H e l l o , w o r l d ! \0
^
|
+------ Pointer to string
...我们可以看到,在!
字符之后逻辑上字符串就结束了。 如果没有\0
(或任何其他确定其结尾的方法),在内存中查找时,我们怎么知道已经完成了该字符串? 其他语言将字符串长度与字符串类型一起传递以解决这个问题。
当我的计算机基础知识有限时,我曾问过这个问题,而这个答案是许多年前对我很有帮助的答案。 我希望它也能帮助其他人。:)
C字符串是字符数组,C数组只是指向内存位置的指针,该位置是数组的起始位置。但是数组的长度(或结束)也必须以某种方式表示;在字符串的情况下,使用空终止符。另一种选择是将字符串的长度与内存指针一起传递,或者将长度放在第一个数组位置中,或者其他什么方式。这只是一种约定。
像Java或PHP这样的高级语言会自动透明地存储数组的大小信息,因此用户不必担心它们。
C语言本身没有字符串的概念。字符串只是字符数组(对于Unicode等使用wchar的情况也是如此)。
由于这些事实,C语言无法检查字符串的长度,因为没有“mystring->length”这样的东西,也没有设置长度值的地方。找到字符串的结尾的唯一方法是遍历它并检查\0。
C语言中有一些使用结构体的字符串库。
struct string {
int length;
char *data;
};
为了消除对\0结尾的需求,但这不是标准C语言。
C++、PHP、Perl等语言有自己的内部字符串库,通常具有单独的长度字段,可以加速某些字符串函数并消除对\0的需求。
其他一些语言(如Pascal)使用称为Pascal字符串的字符串类型,它将长度存储在字符串的第一个字节中,这就是为什么这些字符串的长度限制为255个字符的原因。
class string
{
int length;
char[] data;
}
但你只能将其视为普通字符串,没有长度字段,因为这可以由语言的运行时环境计算,并且仅在内部使用它来正确分配和访问内存。
这是一种约定 - 可以使用另一种算法(例如,在缓冲区开头处放置长度)来实现它。
在汇编等“低级”语言中,有效地测试“NULL”很容易:这可能会使决定使用以NULL结尾的字符串而不是跟踪长度计数器更加容易。
它们需要以空字符结尾,这样你就知道它们的长度。是的,它们只是char数组。
像PHP这样的高级语言可能会选择隐藏空字符终止符,或者根本不使用它 - 例如,它们可能会保持一个长度。C语言不会这样做,因为涉及到了额外的开销。高级语言也可能不将字符串实现为char数组 - 例如,它们可以(并且一些语言确实这样做)将其实现为char数组的列表。
它们是以空字符结尾的,因为许多标准库函数期望它们是这样的。