- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在使用 c 的 Linux 中,当我读/写二进制缓冲区时,我不明白 char*
和 unsigned char*
之间有什么区别?
当我不能使用 char*
而需要使用 unsigned char*
时?
最佳答案
首先记忆C有unsigned char
, signed char
和 char
: 3种不同的类型。 char
与 unsigned char
具有相同的范围或 signed char
.
[编辑]
OP 添加了“当我读/写二进制缓冲区时”,所以下面的部分(我的原始帖子)处理“char*
和 unsigned char*
之间的区别是什么”,并带有一个示例案例,没有 r/w 问题.在本节中....
通过 <stdio.h>
读取/写入二进制文件可以用任何 I/O 函数完成,尽管使用 fread()/fwite()
更常见.
对于面向字节的数据,所有 I/O 函数的行为就好像
The byte input functions read characters from the stream as if by successivecalls to the
fgetc
function. C17dr § 7.21.3 11
The byte output functions write characters to the stream as if by successivecalls to thefputc
function. § 7.21.3 12
那么让我们看看这两个。
... the
fgetc
function obtains that character as anunsigned char
... § 7.21.7.1 2
Thefputc
function writes the character specified by c (converted to anunsigned char
) § 7.21.7.3 2
因此,最好将最低级别的所有 I/O 视为读/写 unsigned char
.
现在直接地址
When I must not using
char*
and need to useunsigned char*
? (OP)
有了写法,指针如char*
, unsigned char*
或其他可以在 OP 级代码中使用,但底层输出函数通过 unsigned char *
访问数据.这对 OP 的写入执行没有影响,除非 char
。被编码为 ones 的补码/符号幅度 - 不会检测到陷阱代码。
与阅读一样,底层输入函数通过unsigned char *
保存数据。并且没有陷阱发生。通过 int fgetc()
读取单个字节将在 unsigned char
中报告值范围即使char
已签名。
使用 unsigned char*
的重要性与 char*
在读/写二进制缓冲区中,与其说是 I/O 调用本身(所有 unsigned char *
访问),不如说是在写入前设置数据和读取后解释数据 - 参见 memcmp()
下面。
When I must not using
char*
and need to useunsigned char*
?
一个很好的例子是与字符串相关的代码。
尽管在 <string.h>
中起作用使用 char*
在函数参数中,实现就像 char
一样执行是unsigned char
,即使 char
已签名。
For all functions in this subclause, each character shall be interpreted as if it had the type
unsigned char
(and therefore every possible object representation is valid and has a different value). C17dr § 7.24.1 3
所以即使char
是一个签名 char
, 功能类似于 int strcmp(char *a, char *b)
表现得好像 int strcmp(unsigned char *a, unsigned char *b)
.
当字符串因有符号 而异时,这会有所不同 char c
和 char d
具有不同符号的值。
例如。假设 c < 0, d > 0
//通过 char *
访问和 char
已签署c < d 为真//通过 unsigned char *
访问c > d 为假
这导致与 strcmp()
不同的符号返回等影响排序字符串。
// Incorrect code when `char` is signed.
int strcmp(const char *a, const char *b) {
while (*a == *b && *a) { a++; b++; }
return (*a > *b) - (*a < *b);
}
// Correct code when `char` is signed or unsigned, 2's complement or not
int strcmp(const char *a, const char *b) {
const char *ua = a;
const char *ub = b;
while (*ua == *ub && *ua) { ua++; ub++; }
return (*ua > *ub) - (*ua < *ub);
}
[编辑]
同样适用于读取二进制数据并与memcmp()
进行比较.
+0 在正确地视为 unsigned char
时结束了一个字符串. -0 不是终止字符串的空字符,即使是已签名 char
它的值为零。
// Incorrect code when `char` is signed and not 2's complement.
// Conversion to `unsigned char` done too late.
int strcmp(const char *a, const char *b) {
while ((unsigned char)*a == (unsigned char)*b && (unsigned char)*a) { a++; b++; }
return ((unsigned char)*a > (unsigned char)*b) - ((unsigned char)*a < (unsigned char)*b);
}
关于char * vs unsigned char* 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62442859/
这个问题在这里已经有了答案: Why don't Java's +=, -=, *=, /= compound assignment operators require casting? (11 个
当我尝试运行以下代码时,List(.of) 无法编译并给出主题错误。 package collections; import java.util.LinkedHashSet; import java.
我正在尝试编译使用 ChatScript 库的程序。这是我在名为 main.cpp 的文件中的代码: #include #include "common.h" using namespace std
我想在我的程序中外部使用 ChatScript。在documents它说: Embedding Step #1 First, you will need to modify `common.h and
假设我有一个 char,我想用一行代码将其 strcat() 转换为 char 数组。对于 [一个非实用的] 示例: strcat("ljsdflusdfg",getchar()); 或者我想做相反的
我有以下类型签名: *Main Lib> let f :: a -> a -> a -> a; f = undefined *Main Lib> let x :: Char; x = undefin
我正在学习如何在 C 中使用指针(使用 malloc 和 free),但我在这个练习中遇到了一些麻烦。我只想制作一个指针数组,我想在其中保存每个单词的方向。然后我想为一个特定的词做一个 free(),
我有一个字符*: char* version = "10.5.108"; 我想通过字符分隔符获取两个新的 char*。 char delimiter = '.'; 执行以下代码后: printf("|
最近在学习Cpp,今天在学习使用Clion做测试的时候,发生了奇怪的事情。 这是我的代码 int main() { char c = 'b'; char carr[1]{'a'};
我对 c 很陌生,我正在审查一些代码。我遇到了这个: static char * fromDataType; static char * toDataType; static char * fromR
我有一个像这样的动态结构: struct network { int count; char** ips; } 如果我知道每个字符串数组都是 16 个字节(即 INET_ADDRSTR
我有一个旧程序,其中使用了一些库函数,但我没有那个库。 所以我正在使用 C++ 库编写该程序。在那个旧代码中有一些函数是这样调用的 *string = newstrdup("这里有一些字符串"); 字
我正在编写一个函数,该函数接受 ArrayList,然后将每个 char[] 复制到另一个增加长度的 char[] 中,然后将新的 char[] 添加到新的 ArrayList 中。当我尝试复制数组时
我正在寻找 map >并生成每个可能的 map从它。 我知道这可能会占用大量内存并需要一些时间。 每个map需要包含每个字母 a-z,并映射到唯一的 a-z 字符。 IE。啊bjcp迪EVfh嘎血红蛋
#define NAME_LEN 20 #include "stdio.h" #include "stdlib.h" #include "string.h" #pragma warning(disab
所以我必须创建一个函数来找到一对带有第一个字母并返回第二个字母的函数。 我实际上找到了一个答案,但是使用 map 功能却找不到。 lookUp :: Char -> [(Char, Cha
我最近接受采访并要求写mystrcat(*s1, *s2, *s3) 其中s1 和s2 是源字符串连接结果由 s3 给出。有人告诉我,不要担心 s3 的内存分配,并假设 s1 和 s2 不是空/无效字
今天我与一位同事讨论了他(对我来说)不寻常的“main”函数签名。他喜欢这样声明: int main(int argc, char* (*argv)[]) { printf("at index
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicate: What's the difference between new char[10] and new cha
通常字符串文字是 const char[] 类型。但是当我把它当作其他类型时,我得到了奇怪的结果。 unsigned char *a = "\355\1\23"; 使用此编译器会抛出警告“初始化中的指
我是一名优秀的程序员,十分优秀!