C的流中字符的含义
Meaning of character in C's streams
我对C的流抽象中字符的含义的理解似乎有一个盲点;我就是无法将图片拼接在一起。
字符相对于二进制流的含义是什么?
从 7.19.7.1p2 ...
If the end-of-file indicator for the input stream pointed to by stream is not set and a next character is present, the fgetc function obtains that character as an unsigned char converted to an int and advances the associated file position indicator for the stream (if defined).
...
假设我在字符需要 16 位的机器上写了一个文件,然后我开始在字符适合 7 位的机器上读取。那么每次调用 fgetc 时我实际读到的是什么?它是 16 位字符的一部分(即,我一次读取 7 位)还是 16 位字符 "squezzed" 转换为 7 位表示并丢失信息?
来自规范:
3.7.1
1 character
single-byte character
〈C〉 bit representation that fits in a byte
和:
3.6
1 byte
addressable unit of data storage large enough to hold any member of the basic character set of the execution
environment
NOTE 1 It is possible to express the address of each
individual byte of an object uniquely.
NOTE 2 A byte is composed
of a contiguous sequence of bits, the number of which is
implementation- defined. The least significant bit is called the
low-order bit; the most significant bit is called the high-order bit.
所以在您的书写机器上,char
可能是 16 位类型。在您的阅读机上,char
可能是 8 位类型。 C 要求 char
至少是 8 位类型:
5.2.4.2.1 Sizes of integer types
...
— number of bits for smallest object that is not a bit-field (byte)
CHAR_BIT 8
因此,在您的阅读机上,您需要调用两次 fgetc
来读取您在原始机器上写入的 16 位字符的每一半。
char*
是声明指向 char
变量的指针的方式。当你想要一个长度未知的字符串时,它很有用。
第一个例子:
char name[10];
strcpy (name, "type_your_name_here"); //overwrites the first argument with the second.
这里预留10块内存。你可能会全部使用它们,或者你的名字可能只是“Jack”,如果我们考虑到每个字符串末尾的 '[=14=]'
特殊字符,它只需要 5 个内存块。这意味着您还有 5 个未使用的部分。
也许你的名字超过了10个字符,那么你会将多余的存储在哪里?你将做不到。因为您对字符数组进行了静态声明。
第二个例子:
char *name;
这意味着您刚刚声明了指针变量,您将在其中存储字符串中第一个字符的地址。它为您的使用提供了更多的自由和灵活性。无论您的名字是长是短,strcpy
和 strcat
等预定义字符串函数都可以为您处理内存分配。
简而言之:
我的理解是,在第一个示例中,您同时定义了字符串的起点和终点,这限制了您可以容纳的内容,并且还会浪费内存 space。在第二个示例中,您仅指定了授予更多使用自由度和内存经济性的起点。我不知道第二个例子有什么缺点,这也是我学习这个的第一年。所以也许专家们能比我更清楚地阐明这个问题。
从技术上讲,char
是一种单字节类型,可以容纳从 -128 到 127 的值;根据体系结构,它也可以是 unsigned
,保存从 0 到 255 的值。但是尽管严格来说它是一个整数类型,但它通常不用于保存整数。您几乎总是会使用类型 int
或其众多变体之一。
类型 char
,在实践中有几个专门用途:
它可以保存一个ASCII值。由于有 128 个 ASCII 码,或者在某些扩展版本中有 255 个 ASCII 码,因此 char
是用于此目的的理想类型。但是当它以这种方式使用时,它几乎总是作为字符串的一部分出现在程序中,字符串(在 C 中,尽管在 C++ 中并不总是)是 char
.
的简单数组
如果您正在设计一个紧凑的结构,并且您想要创建一个永远不会包含超过 256 个不同值的字段(即数据成员),您可能想要使用 char
也为此目的键入。
请注意,这里有一点对新 C 程序员来说并不总是很明显。您可以将 ASCII 代码分配给 char
变量,但这实际上并不是 C 中 char
的 属性。例如,我可以将 ASCII 代码数字分配给任何整数字段。 C 语言本身并不阻止这一点。但请记住,C 字符串库函数设计用于 char
的数组,而不是 int
.
的数组
我对C的流抽象中字符的含义的理解似乎有一个盲点;我就是无法将图片拼接在一起。
字符相对于二进制流的含义是什么?
从 7.19.7.1p2 ...
If the end-of-file indicator for the input stream pointed to by stream is not set and a next character is present, the fgetc function obtains that character as an unsigned char converted to an int and advances the associated file position indicator for the stream (if defined).
...
假设我在字符需要 16 位的机器上写了一个文件,然后我开始在字符适合 7 位的机器上读取。那么每次调用 fgetc 时我实际读到的是什么?它是 16 位字符的一部分(即,我一次读取 7 位)还是 16 位字符 "squezzed" 转换为 7 位表示并丢失信息?
来自规范:
3.7.1
1 character
single-byte character
〈C〉 bit representation that fits in a byte
和:
3.6
1 byte
addressable unit of data storage large enough to hold any member of the basic character set of the execution environment
NOTE 1 It is possible to express the address of each individual byte of an object uniquely.
NOTE 2 A byte is composed of a contiguous sequence of bits, the number of which is implementation- defined. The least significant bit is called the low-order bit; the most significant bit is called the high-order bit.
所以在您的书写机器上,char
可能是 16 位类型。在您的阅读机上,char
可能是 8 位类型。 C 要求 char
至少是 8 位类型:
5.2.4.2.1 Sizes of integer types
...
— number of bits for smallest object that is not a bit-field (byte)
CHAR_BIT 8
因此,在您的阅读机上,您需要调用两次 fgetc
来读取您在原始机器上写入的 16 位字符的每一半。
char*
是声明指向 char
变量的指针的方式。当你想要一个长度未知的字符串时,它很有用。
第一个例子:
char name[10];
strcpy (name, "type_your_name_here"); //overwrites the first argument with the second.
这里预留10块内存。你可能会全部使用它们,或者你的名字可能只是“Jack”,如果我们考虑到每个字符串末尾的 '[=14=]'
特殊字符,它只需要 5 个内存块。这意味着您还有 5 个未使用的部分。
也许你的名字超过了10个字符,那么你会将多余的存储在哪里?你将做不到。因为您对字符数组进行了静态声明。
第二个例子:
char *name;
这意味着您刚刚声明了指针变量,您将在其中存储字符串中第一个字符的地址。它为您的使用提供了更多的自由和灵活性。无论您的名字是长是短,strcpy
和 strcat
等预定义字符串函数都可以为您处理内存分配。
简而言之:
我的理解是,在第一个示例中,您同时定义了字符串的起点和终点,这限制了您可以容纳的内容,并且还会浪费内存 space。在第二个示例中,您仅指定了授予更多使用自由度和内存经济性的起点。我不知道第二个例子有什么缺点,这也是我学习这个的第一年。所以也许专家们能比我更清楚地阐明这个问题。
从技术上讲,char
是一种单字节类型,可以容纳从 -128 到 127 的值;根据体系结构,它也可以是 unsigned
,保存从 0 到 255 的值。但是尽管严格来说它是一个整数类型,但它通常不用于保存整数。您几乎总是会使用类型 int
或其众多变体之一。
类型 char
,在实践中有几个专门用途:
它可以保存一个ASCII值。由于有 128 个 ASCII 码,或者在某些扩展版本中有 255 个 ASCII 码,因此 char
是用于此目的的理想类型。但是当它以这种方式使用时,它几乎总是作为字符串的一部分出现在程序中,字符串(在 C 中,尽管在 C++ 中并不总是)是 char
.
如果您正在设计一个紧凑的结构,并且您想要创建一个永远不会包含超过 256 个不同值的字段(即数据成员),您可能想要使用 char
也为此目的键入。
请注意,这里有一点对新 C 程序员来说并不总是很明显。您可以将 ASCII 代码分配给 char
变量,但这实际上并不是 C 中 char
的 属性。例如,我可以将 ASCII 代码数字分配给任何整数字段。 C 语言本身并不阻止这一点。但请记住,C 字符串库函数设计用于 char
的数组,而不是 int
.