C語言常見常用的知識點很多,下面是工作中或者找找工作面試時經常會遇到幾個問題。
1、浮點數(float)怎麼使用串口通信?怎麼拆分?怎麼組合恢復?
//定義數據結構
typedef union{
float Data;//定義浮點數據(佔4個字節)
struct
{
u8 b1,b2,b3,b4;//順序不能調整
}Field;
}FloatToByte_t;
//浮點數轉換成字節(出來即可通過串口發送)
void TransFloatToBytes(FloatToByte_t InData,u8 *buff)
{
*buff++=InData.Field.b1;
*buff++=InData.Field.b2;
*buff++=InData.Field.b3;
*buff++=InData.Field.b4;
}
//將字節轉換為浮點數,從字節回覆為浮點數
float TransBytesToFloat(u8 *buff)
{
FloatToByte_t temp;
temp.Field.b1=*buff++;
temp.Field.b2=*buff++;
temp.Field.b3=*buff++;
temp.Field.b4=*buff++;
return temp.Data;
}
測試代碼如下
void TestFloatToByte(void)
{
bool equal=FALSE;
u8 i,uBuff[4];
float fInput=0.123456,fOutput;
FloatToByte_t InData;
printf(" --------------------------------- \\r\\n");
for(i=0;i<10;i++)
{
fInput+=1.01;//待轉換浮點數據
InData.Data=fInput;
TransFloatToBytes(InData,uBuff);//浮點數轉換為字節
fOutput=TransBytesToFloat(uBuff);//字節轉換為浮點數
if(fInput==fOutput)equal=TRUE;//判斷轉換前後是否相等
else equal=FALSE;
printf(" num=%d fInput=%f fOutput=%f equal=%d\\r\\n",i,fInput,fOutput,equal);
}
printf(" --------------------------------- \\r\\n");
}
測試結果如下圖
2、如何拆分一個16位變量為兩字節?移位法還是除法?結果有什麼不同?
u8 B1,B2;
i16 Temp16A=InputData,Temp16B;
//移位法
B1=(u8)(Temp16A>>8);
B2=(u8)Temp16A;
//除法
B1=(u8)(Temp16A/256);
B2=(u8)(Temp16A%256);
//思考以上兩個方法的不同(假如用於通信,接收方是否能回覆原始數據)
一下是測試功能函數
void TestData(i16 InputData)
{
u8 B1,B2;
i16 Temp16A=InputData,Temp16B;
B1=(u8)(Temp16A>>8);
B2=(u8)Temp16A;
printf(" Temp16A=0x%04X %d\\r\\n",Temp16A,Temp16A);
printf(" A B1=0x%X B2=0x%X\\r\\n",B1,B2);
Temp16B=(B1<<8)+B2;
printf(" 移位法恢復數據 Temp16B=0x%04X %d \\r\\n",Temp16B,Temp16B);
B1=(u8)(Temp16A/256);
B2=(u8)(Temp16A%256);
printf(" A B1=0x%X B2=0x%X\\r\\n",B1,B2);
Temp16B=(B1*256)+B2;
printf(" 除法恢復數據 Temp16B=0x%04X %d \\r\\n",Temp16B,Temp16B);
}
輸出結果如下圖:
由上圖可見移位法拆分與恢復數據正確,除法拆分與恢復數據不一致。編程過程中優先使用移位法拆分變量。當然用聯合體也可以。
3、如何快速高效的計算一個變量1的個數?不使用循環計算?
const u8 TableOf1InVar[]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};//建立1的數據表
u8 GetU8Number1Amount(u8 Data)//計算8位變量1的個數
{
u8 cnt;
cnt=TableOf1InVar[Data & 0x0F];
cnt+=TableOf1InVar[Data>>4];
return cnt;
}
u8 GetU16Number1Amount(u16 Data)//計算16位變量1的個數
{
u8 cnt;
cnt=TableOf1InVar[(Data>>0) & 0x0F];
cnt+=TableOf1InVar[(Data>>4) & 0x0F];
cnt+=TableOf1InVar[(Data>>8) & 0x0F];
cnt+=TableOf1InVar[(Data>>12) & 0x0F];
return cnt;
}
u8 GetU32Number1Amount(u32 Data)//計算32位變量1的個數
{
u8 cnt;
cnt=TableOf1InVar[(Data>>0) & 0x0F];
cnt+=TableOf1InVar[(Data>>4) & 0x0F];
cnt+=TableOf1InVar[(Data>>8) & 0x0F];
cnt+=TableOf1InVar[(Data>>12) & 0x0F];
cnt+=TableOf1InVar[(Data>>16) & 0x0F];
cnt+=TableOf1InVar[(Data>>20) & 0x0F];
cnt+=TableOf1InVar[(Data>>24) & 0x0F];
cnt+=TableOf1InVar[(Data>>28) & 0x0F];
return cnt;
}
4、如何通過一個函數判斷芯片的大小端?是大端返回幀,小端返回假。
typedef union
{
u16 dat;
struct
{
u8 a;
u8 b;
}f;
}MucEndian_t;
bool isBigEnd(u16 data)
{
u8 temp8;
MucEndian_t temp;
temp.dat=data;
temp8=data>>8;
if(temp.f.a==temp8)
return TRUE;
else
return FALSE;
}
5、如何定義一個32位變量其地址指向指定定值?並設置變量值為0x12345678
u32 TestFixVar1 __attribute__((at(0x20000100))) = 0x12345678;
void TestFixVar(void)
{
printf(" X1 TestFixVar=0x%X %X \\r\\n",(u32)(&TestFixVar1),TestFixVar1);//輸出地址與變量的值
TestFixVar1=0x87653421;//更改變量的值
printf(" X2 TestFixVar=0x%X %X \\r\\n",(u32)(&TestFixVar1),TestFixVar1);//輸出地址與變量的值
}
測試結果如下圖:
如上圖可見,變量定位定義與測試輸出一致。
總結:以上就是本次分享的五個C語言基本知識點,希望對大家有用。當然C語言還有很多其他知識點。
閱讀更多 西小岑 的文章