C数组:设置偏移处的元素

C数组:设置偏移处的元素,c,arrays,offset,C,Arrays,Offset,我将一个2D数组声明为 static bool array[ROW][COL]; 对于一个特定的函数,我希望使用字节偏移量来设置一些元素,而不是使用索引,因为这个数组中的布尔值几乎保证每个为1字节 loff_t *offset = 0; 因此,我尝试下面这句话 array + *offset = false; 但是,它编译时带有警告“左值必须作为赋值的左操作数”。此实现有什么问题,如何根据字节偏移量设置数组元素?您可以将偏移量用作2D数组,就像它是1D数组一样,但它并不严格正确,因为您正在

我将一个2D数组声明为

static bool array[ROW][COL];
对于一个特定的函数,我希望使用字节偏移量来设置一些元素,而不是使用索引,因为这个数组中的布尔值几乎保证每个为1字节

loff_t *offset = 0;
因此,我尝试下面这句话

array + *offset = false;

但是,它编译时带有警告“左值必须作为赋值的左操作数”。此实现有什么问题,如何根据字节偏移量设置数组元素?

您可以将偏移量用作2D数组,就像它是1D数组一样,但它并不严格正确,因为您正在对子数组边界以外的区域进行索引:

*(array[0] + *offset) = false;         // not strictly correct
对于这种语法,
offset
必须包含许多
bool
类型,计算如下:

*offset = &array[row][col] - array[0];
或等效地:
*偏移量=&array[row][col]-&array[0][0]

另一种方法是使用字符类型别名,但
bool
可能大于
char
,因此这也不正确:

*((char*)array + *offset) = false;  // potentially incorrect
要处理
bool
大于
char
的情况,我们可以使用:

*(bool *)((char*)array + *offset) = false;  // quite ugly
偏移量
应按以下方式计算:

*offset = (char*)&array[row][col] - (char*)array;

可以在二维阵列中使用偏移,就像它是1D阵列一样,但由于索引超出了子阵列边界,因此该偏移并不严格正确:

*(array[0] + *offset) = false;         // not strictly correct
对于这种语法,
offset
必须包含许多
bool
类型,计算如下:

*offset = &array[row][col] - array[0];
或等效地:
*偏移量=&array[row][col]-&array[0][0]

另一种方法是使用字符类型别名,但
bool
可能大于
char
,因此这也不正确:

*((char*)array + *offset) = false;  // potentially incorrect
要处理
bool
大于
char
的情况,我们可以使用:

*(bool *)((char*)array + *offset) = false;  // quite ugly
偏移量
应按以下方式计算:

*offset = (char*)&array[row][col] - (char*)array;

在字节偏移量
*偏移量
处设置存储在数组
数组
中的
bool
值将如下所示

*(bool *) ((char *) array + *offset) = true;
当然,您必须承担这种访问所带来的所有风险,因为像这样的技术很容易违反严格的别名规则。一个更安全的选择可能是

bool new_value = true;
memcpy((char *) array + *offset, &new_value, sizeof new_value);

在字节偏移量
*偏移量
处设置存储在数组
数组
中的
bool
值将如下所示

*(bool *) ((char *) array + *offset) = true;
当然,您必须承担这种访问所带来的所有风险,因为像这样的技术很容易违反严格的别名规则。一个更安全的选择可能是

bool new_value = true;
memcpy((char *) array + *offset, &new_value, sizeof new_value);

您可以手动计算特定偏移量的索引,而不是在尝试避免未定义行为时通过混淆指针直接指定字节偏移量:

array[offset / COL][offset % COL] = ...

仅当
sizeof(bool)==sizeof(char)
时,上述操作才有效

如果您的程序已经做出了这样的假设,您应该添加以下内容:

static_assert(sizeof (bool) == sizeof (char), "sizeof bool != sizeof char");

如果没有,您应该使用不同的(基于指针的)方法。

您可以手动计算特定偏移量的索引,而不是通过在尝试避免未定义行为时混淆指针来直接指定字节偏移量:

array[offset / COL][offset % COL] = ...

仅当
sizeof(bool)==sizeof(char)
时,上述操作才有效

如果您的程序已经做出了这样的假设,您应该添加以下内容:

static_assert(sizeof (bool) == sizeof (char), "sizeof bool != sizeof char");

如果没有,您应该使用不同的(基于指针的)方法。

@2501:是的,未定义的行为。将
*((char*)数组[0]+*偏移量)=false是否定义并正确?不,因为bool可能不是一个字节。严格阅读该标准,它也可能是不受限制的。虽然它会起作用,但在转换为
char*
之前为什么要执行
array[0]
,还不完全清楚。绝对没有必要执行
[0]
@AnT:确实没有必要执行
[0]
,但我确实喜欢在应用强制转换时保持相同的间接级别:
数组[0]
衰减为
bool*
@chqrlie:相同的间接级别?但是
array
本身衰减为
bool(*)[COL]
。这也是相同的间接层次(即仅一个层次)。C中的显式数组类型不会引入额外的间接寻址级别。@2501:是,未定义的行为。将
*((char*)数组[0]+*偏移量)=false是否定义并正确?不,因为bool可能不是一个字节。严格阅读该标准,它也可能是不受限制的。虽然它会起作用,但在转换为
char*
之前为什么要执行
array[0]
,还不完全清楚。绝对没有必要执行
[0]
@AnT:确实没有必要执行
[0]
,但我确实喜欢在应用强制转换时保持相同的间接级别:
数组[0]
衰减为
bool*
@chqrlie:相同的间接级别?但是
array
本身衰减为
bool(*)[COL]
。这也是相同的间接层次(即仅一个层次)。C中的显式数组类型不会引入额外的间接寻址级别。旁注:是什么让您如此确信“这个数组中的布尔值几乎保证每个为1字节”???顺便说一句,它们要么是1字节,要么不是;在这种情况下,“几乎可以保证”似乎有点不切实际。除非底层架构有位寄存器,否则
bool
的大小(几乎)总是
int
的大小
loff\u t*offset=NULL相同C语言不允许添加两个指针:int offset=0;数组+偏移=假
,这些第二条语句与:
数组[0][offset]=false旁注:是什么让你如此确信“这个数组中的布尔值几乎保证每个为1字节”???顺便说一句,它们要么是1字节,要么不是;在这种情况下,“几乎可以保证”似乎有点不切实际。除非底层架构有位寄存器,否则
bool
的大小(几乎)总是
int
的大小
loff\u t*offset=NULL相同