我试图颠倒C中的位顺序(作业问题,主题:按位运算符)。我找到了this解决方案,但我对使用的十六进制值 - 0x01和0x80感到有些困惑。
unsigned char reverse(unsigned char c) {
int shift;
unsigned char result = 0;
for (shift = 0; shift < CHAR_BITS; shift++) {
if (c & (0x01 << shift))
result |= (0x80 >> shift);
}
return result;
}
我正在努力的book没有讨论这些价值观,所以我不确定如何制作它们。有人可以对这个解决方案有所了解吗?谢谢!
答案 0 :(得分:4)
0x01是最低有效位集,因此十进制值为1.
0x80是8位字节集的最高有效位。如果它存储在一个有符号的char中(在使用二进制补码表示的机器上 - 就像你可能遇到的大多数机器那样),它是最负的值(十进制-128);在unsigned char中,是十进制+128。
成为第二特性的另一种模式是0xFF,所有位都置位;对于有符号字符,这是十进制-1,对于无符号字符,这是255。当然,如果没有设置位,则为0x00或零。
循环在第一个周期执行的操作是检查LSB(最低有效位)是否设置,如果是,则设置结果中的MSB(最高有效位)。在下一个周期,它检查LSB的下一个周期并将下一个设置为MSB等。
| MSB | | | | | | | LSB |
| 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | Input
| 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | Output
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0x80
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0x01
| 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | (0x80 >> 1)
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | (0x01 << 1)
答案 1 :(得分:3)
每个十六进制数字代表4位,所以
解决方案是使用按位运算符来测试和设置值。
表达式:
if (a & b) { ... }
如果'a'和'b'中的相同位为1,执行'...'。
表达式
c |= b
如果'b'中的位为1,则将'c'中的位设置为1。
循环移动测试&amp;设置位线。
祝你好运!答案 2 :(得分:1)
故意将0x01
和0x80
的值用十六进制表示,以强调它们作为类型unsigned char
的最低有效位和最高有效位的重要性。
但是作者犯了几个错误:
CHAR_BITS
的拼写错误:应为CHAR_BIT
。CHAR_BIT
而不是对几乎通用的值8
进行硬编码是实现完全可移植性的宝贵工作,但是通过使用0x80
无效了此工作,只有在以下情况下才有效CHAR_BIT == 8
。0x01 << shift
的类型为shift = CHAR_BIT-1
(而不是sizeof(unsigned char) == sizeof(int)
,在0x01
的平台上,int
的行为unsigned int
不确定) #include <limits.h>
unsigned char reverse(unsigned char c) {
int shift;
unsigned char result = 0;
for (shift = 0; shift < CHAR_BIT; shift++) {
result <<= 1;
result |= c & 1;
c >>= 1;
}
return result;
}
,是不是违反直觉?)。这是在所有符合要求的平台上均可使用的更正版本:
namespace CoreDesk.Api
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = "https://sts.windows.net/7d63a3a5-79de-44c2-b5a3-ec21f4d24329/";
options.Audience = "00000003-0000-0000-c000-000000000000";
options.TokenValidationParameters.ValidateLifetime = true;
options.TokenValidationParameters.ClockSkew = TimeSpan.Zero;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseCors(builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowCredentials()
.AllowAnyHeader());
app.UseAuthentication();
app.UseMvc();
}
}
}
答案 3 :(得分:0)
0x01
表示1-a在一个地方 - 0x80
表示128-a在六十岁的地方。这些数字分别表示8位数中的最低位和最高位。移位它们会为字节中的各个位提供掩码。
编辑:在十六进制数字中,数字的幂为16,而不是10的幂。所以右边的第一个数字是那个地方(0x1 = 1),第二个数字是六个地方(0x10 = 16),第三个数字是二百五十六个地方(0x100 = 256),等等。