%s 或 %c 格式的 C 中 char 数据类型的大小?
The size of char datatype in C which is in format of %s or %c?
在网上查到C编程中char的资料如下:
Datatype Size Range Format
char 1 byte −128 to 127 %c
signed char 1 byte −128 to 127 %c
unsigned char 1 byte 0 to 255 %c
但我知道有 %s 的 char(数据类型)格式,它用于处理字符串。我的问题是:这两种格式的大小和范围有什么区别吗?
谢谢大家!
A char
是单个 character/letter,例如使用 "%c"
打印,例如'X'
.
用 "%s"
打印的是一个由许多字符组成的以零结尾的字符串,例如可以给出"foobar"
。请注意不同的引号。
(顺便说一句,在处理它们并尝试存储它们时,一个常见的错误是没有足够的 space 作为最后的零。通常需要多一个而不是显而易见的。)
比较https://en.cppreference.com/w/cpp/io/c/fprintf
%s
通常指的"range"很难定义。可能是书。
用 %s
打印的内容有时被描述为 "C pseudo-string",但没有这样的数据类型。
C 中的字符串被定义为字符数组,其中包含以零字符“\0”结尾的字符序列。
例如,字符串文字 "Hello"
的类型为 char[6]
(考虑终止零字符)。所以运算符 sizeof( "Hello" )
产生值 6
.
转换说明符%s
指定输出字符串并等待指向字符串第一个字符的指针。字符串的大小仅受所用系统资源的限制,不能大于类型size_t
.
中存储的最大值
Th 转换说明符 %c
旨在输出 char
类型的标量对象。 char
类型的对象的大小等于 1
(sizeof(char )
等于 1
)。请记住,在 C 中,字符文字的类型为 int
。因此,例如 sizeof( 'A' ) 产生 4(如果 int 类型的对象的大小等于 4)。
这是一个演示程序
#include <stdio.h>
int main(void)
{
printf( "sizeof( \"Hello\" ) = %zu\n", sizeof( "Hello" ) );
char c = 'A';
printf( "sizeof( char ) = %zu, sizeof( 'A' ) = %zu\n", sizeof( c ), sizeof( 'A' ) );
return 0;
}
它的输出是
sizeof( "Hello" ) = 6
sizeof( char ) = 1, sizeof( 'A' ) = 4
注意 char
类型的取值范围取决于编译器选项,char 类型可以表现为 signed char
或 unsigned char
类型。所以写
会更正确
char 1 byte −128 to 127 %c
or
char 1 byte 0 to 255 %c
来自 C 标准(5.2.4.2.1 整数类型的大小)
2 If the value of an object of type char is treated as a signed
integer when used in an expression, the value of CHAR_MIN shall be the
same as that of SCHAR_MIN and the value of CHAR_MAX shall be the same
as that of SCHAR_MAX. Otherwise, the value of CHAR_MIN shall be 0 and
the value of CHAR_MAX shall be the same as that of UCHAR_MAX. The
value UCHAR_MAX shall equal 2CHAR_BIT − 1.
%c
用于打印单个字符值,并期望其对应的参数具有类型 char
:
char c = 'A';
printf( "%c\n", c );
%s
用于打印 strings,它们是包含零值终止符的字符值序列,并期望其对应的参数具有类型 char *
(指向char
的指针),也就是字符串第一个字符的地址:
char s[] = "hello"; // equivalent to {'h', 'e', 'l', 'l', 'o', 0}
printf( “%s\n”, s ); // equivalent to passing &s[0]
除非它是 sizeof
或一元 &
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,表达式 类型 "N-element array of T
" 将被转换 ("decay") 为“指向 T
的指针”类型的表达式,表达式的值将是第一个元素的地址数组。所以当我们将 表达式 s
传递给 printf
时,实际传递的是 s[0]
的地址,而不是数组内容本身. 基本等同于写
char s[] = "hello";
char *p = s;
while ( *p != 0 )
putchar( *p++ ); // print the character p points to, then advance
// p to point to the next character in the string
%s
和 %c
不是格式或类型。它们被称为 "conversion or format specifiers",用于关于一种字符类型或字符串的正确格式,由 printf()
和 scanf()
系列的函数使用。因此,他们自己没有"size"或"range"。
Is there any difference in the size and range of these 2 formats?
在 C 语言中,字符串本身不是一种类型。字符串是连续的字符对象序列。
一个字符串的"size"是在源代码中或者程序中确定的运行(variable length arrays);字符串没有一般的固定大小。
字符串与 "range" 不同,它具有字符或整数类型。
你想问的是所有这些字符是否一起(可以)提供更大的范围。答案是否定的。
字符串中的所有字符在内存中都有自己专用的范围和大小,您不能将它们视为一种可以存储和表示更大值的化合物:
char a;
a
的大小为 1 个字节,范围为 -128 到 127 或 0 到 255(取决于实现和平台,但在大多数现代系统上,它的范围为 -128 到 127 ).
char b[4];
b
在这种情况下有 4 个字节的大小,但它的范围不是从 -2,147,483,648 到 2,147,483,647(2³² = 4,294,967,296 个可存储值(注意符号表示的一位))。它仅由 4 个 char
对象组成,每个对象在内存中分配 1 个字节,并且可以 store/represent 值从 −128 到 127/0 到 255。
如果要为单个字符使用更宽的范围,请使用宽字符类型wchar_t
。
C 中没有字符串类型,但 C 标准库确实将字符串定义为以 null 结尾的字符数组 §7.1.1p1 of the C11 Draft Standard
A string is a contiguous sequence of characters terminated by and including the first null character.
OP显示的table是正确的,char
、signed char
、unsigned char
都是1个字节宽。标准中的类型指定了最小值范围,但没有绝对值范围;虽然 table 中的值范围很常见,但不能保证。特别是,char
是值范围为 0 到 255 的无符号类型并不少见。请注意,对于有符号的 char
类型,标准只需要 -127 到 127 的最小范围。即使是字节也必须具有 最小值 8 位宽度,但未指定恰好 8 位。实际细节是实现细节。
%c
和%s
用于格式化I/O操作;这些与类型没有直接关系,而是用于描述函数期望的类型。对于 fprintf()
系列函数,%c
转换说明符告诉函数需要一个整数参数,该参数将被转换为 unsigned char
值并打印为字符。请注意,字符编码不需要是 ASCII(这是另一个实现细节),但这是当今最常见的。
%s
转换说明符告诉 fprintf()
函数期望指向字符数组第一个元素的指针。如果未指定 suitable 精度(例如 %5s
最多打印 5 个字符),则数组必须是字符串(即以 null 结尾)。
对于 fscanf()
系列函数,%c
指令告诉函数扫描输入中的一个或多个字符(即,在提供字段宽度时扫描多个字符,例如 %3c
),并期望指向一个足够大的字符数组来保存结果。对于简单的scanf("%c", &some_char)
,扫描的最大字符数是1,而some_char
只需要是char
,例如定义为 char some_char;
。但是对于像 scanf("%5c", five_chars)
这样的东西,five_chars
必须是一个能够存储 5 char
的数组,例如定义为 char five_chars[5];
.
%s
指令与 fscanf()
函数的操作类似,但没有最大字段宽度规范,这将告诉 fscanf()
尝试匹配和存储字符,直到遇到空格输入。该函数需要一个指向能够保存所有匹配字符(加上空终止符)的字符数组的指针,因此您必须始终指定最大字段宽度以避免潜在的缓冲区溢出。另请注意,%s
指令 always 会导致在扫描最后一个字符后写入 [=38=]
终止符。因此,当存储声明为 char storage[100];
时,使用 scanf("%99s", storage);
是正确的。这告诉 scanf()
在写入最终 [=38=]
之前匹配输入中的 至多 99 个字符,避免写入超过 storage[]
数组的末尾输入大的情况。
关于 fprintf()
and fscanf()
有更多详细信息。请注意,fscanf()
是一个复杂的函数,很难正确使用。
在网上查到C编程中char的资料如下:
Datatype Size Range Format
char 1 byte −128 to 127 %c
signed char 1 byte −128 to 127 %c
unsigned char 1 byte 0 to 255 %c
但我知道有 %s 的 char(数据类型)格式,它用于处理字符串。我的问题是:这两种格式的大小和范围有什么区别吗? 谢谢大家!
A char
是单个 character/letter,例如使用 "%c"
打印,例如'X'
.
用 "%s"
打印的是一个由许多字符组成的以零结尾的字符串,例如可以给出"foobar"
。请注意不同的引号。
(顺便说一句,在处理它们并尝试存储它们时,一个常见的错误是没有足够的 space 作为最后的零。通常需要多一个而不是显而易见的。)
比较https://en.cppreference.com/w/cpp/io/c/fprintf
%s
通常指的"range"很难定义。可能是书。
用 %s
打印的内容有时被描述为 "C pseudo-string",但没有这样的数据类型。
C 中的字符串被定义为字符数组,其中包含以零字符“\0”结尾的字符序列。
例如,字符串文字 "Hello"
的类型为 char[6]
(考虑终止零字符)。所以运算符 sizeof( "Hello" )
产生值 6
.
转换说明符%s
指定输出字符串并等待指向字符串第一个字符的指针。字符串的大小仅受所用系统资源的限制,不能大于类型size_t
.
Th 转换说明符 %c
旨在输出 char
类型的标量对象。 char
类型的对象的大小等于 1
(sizeof(char )
等于 1
)。请记住,在 C 中,字符文字的类型为 int
。因此,例如 sizeof( 'A' ) 产生 4(如果 int 类型的对象的大小等于 4)。
这是一个演示程序
#include <stdio.h>
int main(void)
{
printf( "sizeof( \"Hello\" ) = %zu\n", sizeof( "Hello" ) );
char c = 'A';
printf( "sizeof( char ) = %zu, sizeof( 'A' ) = %zu\n", sizeof( c ), sizeof( 'A' ) );
return 0;
}
它的输出是
sizeof( "Hello" ) = 6
sizeof( char ) = 1, sizeof( 'A' ) = 4
注意 char
类型的取值范围取决于编译器选项,char 类型可以表现为 signed char
或 unsigned char
类型。所以写
char 1 byte −128 to 127 %c
or
char 1 byte 0 to 255 %c
来自 C 标准(5.2.4.2.1 整数类型的大小)
2 If the value of an object of type char is treated as a signed integer when used in an expression, the value of CHAR_MIN shall be the same as that of SCHAR_MIN and the value of CHAR_MAX shall be the same as that of SCHAR_MAX. Otherwise, the value of CHAR_MIN shall be 0 and the value of CHAR_MAX shall be the same as that of UCHAR_MAX. The value UCHAR_MAX shall equal 2CHAR_BIT − 1.
%c
用于打印单个字符值,并期望其对应的参数具有类型 char
:
char c = 'A';
printf( "%c\n", c );
%s
用于打印 strings,它们是包含零值终止符的字符值序列,并期望其对应的参数具有类型 char *
(指向char
的指针),也就是字符串第一个字符的地址:
char s[] = "hello"; // equivalent to {'h', 'e', 'l', 'l', 'o', 0}
printf( “%s\n”, s ); // equivalent to passing &s[0]
除非它是 sizeof
或一元 &
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,表达式 类型 "N-element array of T
" 将被转换 ("decay") 为“指向 T
的指针”类型的表达式,表达式的值将是第一个元素的地址数组。所以当我们将 表达式 s
传递给 printf
时,实际传递的是 s[0]
的地址,而不是数组内容本身. 基本等同于写
char s[] = "hello";
char *p = s;
while ( *p != 0 )
putchar( *p++ ); // print the character p points to, then advance
// p to point to the next character in the string
%s
和 %c
不是格式或类型。它们被称为 "conversion or format specifiers",用于关于一种字符类型或字符串的正确格式,由 printf()
和 scanf()
系列的函数使用。因此,他们自己没有"size"或"range"。
Is there any difference in the size and range of these 2 formats?
在 C 语言中,字符串本身不是一种类型。字符串是连续的字符对象序列。
一个字符串的"size"是在源代码中或者程序中确定的运行(variable length arrays);字符串没有一般的固定大小。
字符串与 "range" 不同,它具有字符或整数类型。
你想问的是所有这些字符是否一起(可以)提供更大的范围。答案是否定的。
字符串中的所有字符在内存中都有自己专用的范围和大小,您不能将它们视为一种可以存储和表示更大值的化合物:
char a;
a
的大小为 1 个字节,范围为 -128 到 127 或 0 到 255(取决于实现和平台,但在大多数现代系统上,它的范围为 -128 到 127 ).
char b[4];
b
在这种情况下有 4 个字节的大小,但它的范围不是从 -2,147,483,648 到 2,147,483,647(2³² = 4,294,967,296 个可存储值(注意符号表示的一位))。它仅由 4 个 char
对象组成,每个对象在内存中分配 1 个字节,并且可以 store/represent 值从 −128 到 127/0 到 255。
如果要为单个字符使用更宽的范围,请使用宽字符类型wchar_t
。
C 中没有字符串类型,但 C 标准库确实将字符串定义为以 null 结尾的字符数组 §7.1.1p1 of the C11 Draft Standard
A string is a contiguous sequence of characters terminated by and including the first null character.
OP显示的table是正确的,char
、signed char
、unsigned char
都是1个字节宽。标准中的类型指定了最小值范围,但没有绝对值范围;虽然 table 中的值范围很常见,但不能保证。特别是,char
是值范围为 0 到 255 的无符号类型并不少见。请注意,对于有符号的 char
类型,标准只需要 -127 到 127 的最小范围。即使是字节也必须具有 最小值 8 位宽度,但未指定恰好 8 位。实际细节是实现细节。
%c
和%s
用于格式化I/O操作;这些与类型没有直接关系,而是用于描述函数期望的类型。对于 fprintf()
系列函数,%c
转换说明符告诉函数需要一个整数参数,该参数将被转换为 unsigned char
值并打印为字符。请注意,字符编码不需要是 ASCII(这是另一个实现细节),但这是当今最常见的。
%s
转换说明符告诉 fprintf()
函数期望指向字符数组第一个元素的指针。如果未指定 suitable 精度(例如 %5s
最多打印 5 个字符),则数组必须是字符串(即以 null 结尾)。
对于 fscanf()
系列函数,%c
指令告诉函数扫描输入中的一个或多个字符(即,在提供字段宽度时扫描多个字符,例如 %3c
),并期望指向一个足够大的字符数组来保存结果。对于简单的scanf("%c", &some_char)
,扫描的最大字符数是1,而some_char
只需要是char
,例如定义为 char some_char;
。但是对于像 scanf("%5c", five_chars)
这样的东西,five_chars
必须是一个能够存储 5 char
的数组,例如定义为 char five_chars[5];
.
%s
指令与 fscanf()
函数的操作类似,但没有最大字段宽度规范,这将告诉 fscanf()
尝试匹配和存储字符,直到遇到空格输入。该函数需要一个指向能够保存所有匹配字符(加上空终止符)的字符数组的指针,因此您必须始终指定最大字段宽度以避免潜在的缓冲区溢出。另请注意,%s
指令 always 会导致在扫描最后一个字符后写入 [=38=]
终止符。因此,当存储声明为 char storage[100];
时,使用 scanf("%99s", storage);
是正确的。这告诉 scanf()
在写入最终 [=38=]
之前匹配输入中的 至多 99 个字符,避免写入超过 storage[]
数组的末尾输入大的情况。
关于 fprintf()
and fscanf()
有更多详细信息。请注意,fscanf()
是一个复杂的函数,很难正确使用。