#include <stdio.h>
#include <stdlib.h>
#define BYTETOBINARYPATTERN "%d%d%d%d%d%d%d%d"
#define BYTETOBINARY(byte) \
(byte & 0x80 ? 1 : 0), \
(byte & 0x40 ? 1 : 0), \
(byte & 0x20 ? 1 : 0), \
(byte & 0x10 ? 1 : 0), \
(byte & 0x08 ? 1 : 0), \
(byte & 0x04 ? 1 : 0), \
(byte & 0x02 ? 1 : 0), \
(byte & 0x01 ? 1 : 0)
#define PRINTBIN(x) printf(BYTETOBINARYPATTERN, BYTETOBINARY(x));
void printarr(unsigned char *p);
void setlsbs(unsigned char *p, unsigned char b0);
unsigned char getlsbs(unsigned char *p);
int main(int argc, char *argv[])
{
unsigned char arr[7];
unsigned char byte0, byte1;
int i;
if (argc != 2) {
printf("Error.Invalid arguments.\n");
exit(1);
}
//seed random
srandom(atoi(argv[1]));
for (i = 0; i < 8; i++)
arr[i] = random() % 255+1;
byte0 = random() % (255 + 1);
printarr(arr);
printf("\nbyte0: ");
PRINTBIN(byte0);
printf(" %d\n\n",byte0);
setlsbs(arr, byte0);
printarr(arr);
byte1 = getlsbs(arr);
printf("\nbyte1: ");
PRINTBIN(byte1);
printf(" %d\n\n", byte1);
return 0;
}
void printarr(unsigned char *p)
{
int i;
for (i = 0; i < 8; i++) {
PRINTBIN(p[i]);
printf(" %d\n", p[i]);
}
}
void setlsbs(unsigned char *p, unsigned char b0)
{
int i, counter;
unsigned char x;
x = b0;
for (i = 0, counter = 1; i < 8; i++, counter++) {
p[i] &= 0xFE;
x &= 0x01;
p[i] |= x;
x = b0;
x >>= counter;
}
}
unsigned char getlsbs(unsigned char *p)
{
int i, counter;
unsigned char b0 = 0;
for (i = 0; i < 8; i++) {
p[i] &= 0x01;
b0 |= p[i];
b0 <<= 1;
}
return b0;
}
我正在尝试将byte1
设置为数组中元素的最不重要的数字。例如,p[0]
的最右边位是字节1的最左边的位。p[1]
的最右边的字节将是字节1的第二位,依此类推。该代码适用于某些数字,但它不适用于其他人,我无法弄明白。我认为我的算法是正确的。
运行代码:
John Doe@DESKTOP-QFEGQQD ~/learn
$ ./lab11 50
00110101 53
10100110 166
01101101 109
11001001 201
10111101 189
01000101 69
10010011 147
10000001 129
byte0: 01011001 89
00110101 53
10100110 166
01101100 108
11001001 201
10111101 189
01000100 68
10010011 147
10000000 128
byte1: 00110100 52
Byte1应该等于Byte0。
答案 0 :(得分:3)
arr
被声明为7元素数组,而您将其作为8元素访问。它导致了未定义的行为,这解释了&#34;有时是有效的,有时不是&#34;。
答案 1 :(得分:2)
您当然应该将arr
中数组main
的定义修复为8个字节:
unsigned char arr[8];
此外,getlsbs
中的方法不正确:您应该将字符移位到之前或下一位,否则会丢失最高位并始终将低位设置为0你不需要为此修改参数缓冲区,这是一个令人讨厌的副作用。另请注意,您的算法实际上会将b0
中的位转换为b1
。你的评论并不明显,你的意思是。
以下是修改后的版本:
unsigned char getlsbs(unsigned char const *p) {
int i;
unsigned char b0 = 0;
for (i = 0; i < 8; i++) {
b0 = (b0 << 1) | (p[i] & 1);
}
return b0;
}
我不得不重新编写代码以使其可读。不要在源文件中使用TAB,忘记愚蠢的/* end if */
注释。 {@ 1}}宏也应该修复:您应该在扩展中用括号保护BYTETOBINARY
。它不会导致错误,但byte
会失败。