因此,我需要一些帮助来解决此问题。我有这样的作业:
typedef struct {
char status[1];
} Dish;
变量status
只能有1个字节:前3位将包含碟子的星数(0-5),第4位告诉我们是否取消了碟子,第5位告诉我们是否菜是否在进行中。我试图获得像这样的星星数量,但它不起作用:
getBit(char data, int bitNumber) {
return (data & (1 << bitNumber-1)) != 0;
}
int number = 0;
number = getBit(dish.status,0);
number = number << 1 + getBit(dish.status,1);
number = number << 1 + getBit(dish.status,2);
因为status
只能有1个字节,所以我在上面声明了它char status[1]
是否正确?我也尝试直接在status
上使用二进制运算,但是它给我一个错误,提示我不能在char
和int
之间使用二进制运算。我的最终目标是将该字节中的所有信息放入一个单独的变量中:stars
,canceled
,ongoing
。
[将数据成员状态声明为具有一个元素的数组没有太大意义
char status[1];
您可以这样声明
unsigned char status;
该函数看起来像在下面的演示程序中所示。
#include <stdio.h>
#include <limits.h>
unsigned int getBit( unsigned char data, unsigned int bitNumber )
{
bitNumber %= CHAR_BIT;
return ( data & (1 << bitNumber ) ) != 0;
}
int main(void)
{
for ( int i = 0; i <3; i++ )
{
printf( "%d\n", getBit( 6, i ) );
}
return 0;
}
程序输出为
0
1
1
另一方面,由于数据成员status
由位字段组成,因此除了提取一位以外,您还可以对每个位字段使用掩码来提取它。
[另一种方法是使用位字段代替unsigned char类型的对象。有点像
typedef struct {
unsigned char stars: 3;
unsigned char cancelled: 1;
//...
} Dish;
建议的答案可以完成工作。如果您不想进行移位操作,请尝试以下方法:
typedef struct dist {
union {
uint8_t number_of_stars : 3 ;
uint8_t cancel_status : 1 ;
uint8_t ongoing_status :1 ;
uint8_t reserved : 3;
struct {
uint8_t status;
};
};
} DishType;
DishType Dish;
如果检查Dish
的大小,您会发现它仍然占用一个字节的内存。
您可以在一行中设置参数,例如:
Dish.status = 0x0C; // For example
或者您可以设置特定的参数,例如:
Dish.cancel_status = 1;
Dish.ongoing_status = 0;
但是,仍然可以单独访问或打印或修改它:
printf("\nNo. of starts = %u", Dish.number_of_stars);
通过一些调整,您的代码有效:
int getBit(char data, size_t bitNumber) {
return (data & (1 << (bitNumber - 1))) != 0;
}
int main(void) {
char status = 3 + (1 << 5);
for (size_t i = 1; i <= 8; ++i) {
printf("Bit %d: %d\n", (int) i, getBit(status, i));
}
return 0;
}
我使用size_t表示位数(无符号),并在术语周围固定了花括号。
使用位字段,代码可能如下所示:
#include <stdio.h>
typedef struct {
union {
struct {
char stars:3;
char cancelled:1;
char ongoing:1;
};
char data;
};
} Dish;
void printDish(Dish dish) {
printf("Stars = %d, Cancelled = %d, Ongoing = %d\nValue: %d\n", dish.stars, dish.cancelled, dish.ongoing, dish.data);
}
int main(void) {
Dish dish1;
dish1.stars = 3;
dish1.cancelled = 1;
dish1.ongoing = 1;
printDish(dish1);
Dish dish2;
dish2.stars = 5;
dish2.cancelled = 0;
dish2.ongoing = 0;
printDish(dish2);
return 0;
}
这将输出:
clang version 7.0.0-3~ubuntu0.18.04.1 (tags/RELEASE_700/final)
clang-7 -pthread -lm -o main main.c
./main
Stars = 3, Cancelled = -1, Ongoing = -1
Value: 99
Stars = 5, Cancelled = 0, Ongoing = 0
Value: 5
您可以使用.data访问其他'char'值,并使用命名字段访问其他所有内容。如果要投射(通过fread)读取的文件,则可能要确保该结构的对齐正确。