質問 1: シングル
配列内に 1 回出現する数値は 2 つだけで、他の数値はすべて 2 回出現します。
1 回だけ出現する 2 つの数値を見つける関数を作成します。
たとえば、
配列の要素は 1、2、3、4、5、1、2、3、4、6 です。5 と 6 を
見つけるには、5 と 6 が 1 回だけ現れます。
#include <stdio.h>
int* find_signal_dog(int* arr,int sz,int* signal_dog)
{
int i = 0;
int tmp = 0;
for (i = 0; i < sz; i++)
{
tmp ^= arr[i];//得到不相同的两个数的按位异或
}
int pos = 0;
for (i = 0; i < 32; i++)
{
//得出向右移动多少位按位与结果为一
if (((tmp >> i) & 1) == 1)
{
pos = i;
break;
}
}
for (i = 0; i < sz; i++)
{
//将&为一和零的各分一组,再异或得到不同的两个数
if (((arr[i] >> pos) & 1) == 1)
{
signal_dog[0] ^= arr[i];
}
else
{
signal_dog[1] ^= arr[i];
}
}
}
int main()
{
int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* signal_dog[2] = { 0 };
find_signal_dog(arr, sz, signal_dog);
printf("%d %d\n",signal_dog[0] , signal_dog[1]);
return 0;
}
間違った多肢選択
以下のマクロ定義と構造体定義があります。
A=2、B=3 の場合、ポインタは ( ) バイトのスペースを割り当てます。
int main()
{
unsigned char puc[4];
struct tagPIM
{
unsigned char ucPim1;
unsigned char ucData0 : 1;
unsigned char ucData1 : 2;
unsigned char ucData2 : 3;
}*pstPimData;
pstPimData = (struct tagPIM*)puc;
memset(puc,0,4);
pstPimData->ucPim1 = 2;
pstPimData->ucData0 = 3;
pstPimData->ucData1 = 4;
pstPimData->ucData2 = 5;
printf("%02x %02x %02x %02x\n",puc[0], puc[1], puc[2], puc[3]);
return 0;
}
A.20
B.15
C.11
D.9
説明: 構造は最長の文字に合わせて配置されます。最初の 2 ビット セグメント要素は合計 4+2 ビットで、8 ビット未満です。これらは合計 1 バイトを占め、最後の要素は 1 バイトだけです。合計3バイト。また、#define で検索と置換が行われるため、sizeof(struct _Record_Struct) * MAX_SIZE は実際には 3*2+3 となり、結果は 9 となるため、D を選択します。
X86、リトルエンディアンバイトオーダーストレージでは、次のプログラムがあります。
#include<stdio.h>
int main()
{
union
{
short k;
char i[2];
}*s, a;
s = &a;
s->i[0] = 0x39;
s->i[1] = 0x38;
printf("%x\n", a.k);
return 0;
}
出力結果は( )です。
A.3839
B.3938
C.380039
D. わからない
共用体は 2 バイトしかなく、2 バイトの 16 進数は 4 ビットしかないため、応答 CD は除外されます。ビット順序はリトルエンディアンに似ており、下位アドレスが下位なので39が下位アドレスで下位、38が上位なので3839となるのでAを選択します。
古典的な話題
次のコードの結果は ( ) です。
int main()
{
unsigned char puc[4];
struct tagPIM
{
unsigned char ucPim1;
unsigned char ucData0 : 1;
unsigned char ucData1 : 2;
unsigned char ucData2 : 3;
}*pstPimData;
pstPimData = (struct tagPIM*)puc;
memset(puc,0,4);
pstPimData->ucPim1 = 2;
pstPimData->ucData0 = 3;
pstPimData->ucData1 = 4;
pstPimData->ucData2 = 5;
printf("%02x %02x %02x %02x\n",puc[0], puc[1], puc[2], puc[3]);
return 0;
}
B.02 29 00 00
C.02 25 00 00
D.02 29 04 00
puc は char 配列で、一度に 1 バイトずつジャンプしますが、構造体はそうではありません。1 バイトのみを共有する最初の要素だけがあり、他の 3 つの要素は一緒に 1 バイトを共有します。そのため、puc が構造体によって埋められた後、 、2バイトしか書き込まれません、最後の2バイトは0でなければならないのでADは除外されます、そして最初のバイトは2です、それは2です、2番目のバイトはさらに厄介です、まず第一に、ucData0は3を与えました、これは実際には範囲外です はい、1 桁の数値は 0 または 1 のみであるため、切り捨てられた後は 11 は 1 のみになります。同様に、ucData1 で指定された 4 も範囲外です。100 が切り捨てられると、00 になります。 101 のうち 5 だけが正常です。充填順序はリトル エンディアンの下位アドレスに似ているため、配置順序は 00 101 00 1 になります。それは 0010 1001、つまり 0x29 なので、B を選択します。