C言語: 演習

質問 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 を選択します。

おすすめ

転載: blog.csdn.net/weixin_71964780/article/details/132130443