C/C++: 常见的数据类型转换

简介: 常见的数据类型转换

引言:随着项目的逐渐扩大,软件分层带来的是比如底层和协议栈的数据交互,或者底层和别的底层之间也会有数据交互,不可避免的就是各种各样的数据类型转化的问题,也有一些简单的过滤啊回写啊之类的,把最近遇见过得做个小总结吧:

1 物理地址的读写

void Xil_Out32(unsigned int * Addr, unsigned int Value)
{
  volatile unsigned int *LocalAddr = (volatile unsigned int *)Addr;
  *LocalAddr = Value;
}
 unsigned int  Xil_In32(unsigned int * Addr)
{
  return *(volatile unsigned int *) Addr;
}

2 位操作

倒序

unsigned char  bit_reverse(unsigned char  c)
 {
   unsigned char buf = 0;
   int bit = 8;
   while(bit)
   {
   bit--;
   buf |= ((c & 1) << bit);
   c >>=1;
   }
   return buf;
 }

数0的个数

int CountZeroBit(int num)
{
  int count = 0;
  while (num + 1)
  {
  count++;
  num |= (num + 1); //算法转换
  }
  return count;
}
int main()
{
  int value = 25;
  int ret = CountZeroBit(value);
  printf("%d的二进制位中0的个数为%d\n",value, ret);
  system("pause");
  return 0;
}

数1的个数

#include <stdio.h>
int func(int x)
{
  int countx = 0;
  while(x)
  {
  countx++;
  x = x&(x-1);
  }
  return countx;
}
int main()
{
  printf("%d\n",func(9999));
  return 0;
}

设置如bit3,清除bit3

#define BIT3 (0x1<<3) 
static int a; 
void set_bit3(void) 
{ 
  a |= BIT3; 
} 
void clear_bit3(void) 
{ 
  a &= ~BIT3; 
} 

3 大小端转化

//为大端:
pPack[0] = (u8)((len >> 8) & 0xFF);
pPack[1] = (u8)(len & 0xFF);
//为小端:
pPack[0] = (u8)(len & 0xFF);
pPack[1] =  (u8)((len >> 8) & 0xFF);

4 u8和u32的转化

void U32ToU8Array(uint8_t *buf, uint32_t u32Value)
{
    buf[0] = ((u32Value >> 24) & 0xFF);
    buf[1] = ((u32Value >> 16) & 0xFF);
    buf[2] = ((u32Value >> 8) & 0xFF);
    buf[3] = (u32Value & 0xFF);
}
//注意:这里是字符数组,不是字符串
//字符串是以空字符(\0)结尾的char数组
void U8ArrayToU32(uint8_t *buf, uint32_t *u32Value)
{
    *u32Value = (buf[0] <<24) + (buf[1] <<16) + (buf[2] <<8) + (buf[3] <<0);
}

5十进制和字符串转化

如果只是单个十进制转字符串,使用sprintf函数就可以了。

如果是十进制数组:


u16 DectoStr (u8 *pSrc, u16 SrcLen, u8 *pObj)
{
    u16 i=0;
    for(i=0;    i<SrcLen;   i++)
    {
        sprintf((char *)(pObj + i * 2), "%02d", *(pSrc + i));
    }
    *(pObj + i * 2) = '\0';
    return  (i * 2);
}

数组 5 20转为"520"

而字符串转十进制就比较复杂了

第一种,如果带负号 这个就是atoi函数的实现:

第二种,不带符号StrtoDec

最后一种转化为浮点数

//带符号

int my_atoi(const char *str)
{
    int value = 0;
    int flag = 1; //判断符号
    while (*str == ' ')  //跳过字符串前面的空格
    {
        str++;
    }
    if (*str == '-')  //第一个字符若是‘-’,说明可能是负数
    {
        flag = 0;
        str++;
    }
    else if (*str == '+') //第一个字符若是‘+’,说明可能是正数
    {
        flag = 1;
        str++;
    }//第一个字符若不是‘+’‘-’也不是数字字符,直接返回0
    else if (*str >= '9' || *str <= '0') 
    {
        return 0;    
    }
    //当遇到非数字字符或遇到‘\0’时,结束转化
    while (*str != '\0' && *str <= '9' && *str >= '0')
    {
        value = value * 10 + *str - '0'; //将数字字符转为对应的整形数
        str++;
    }
    if (flag == 0) //负数的情况
    {
        value = -value;
    }
    return value;
}

//不带

void StrtoDec(uint32_t *pbDest, char *pbSrc, int nLen)
{
    int i;
    int tmp=0;
    if(nLen > 10)
        *pbDest = 0;
    tmp = 1;
    *pbDest = 0;
    for (i=nLen-1; i>=0; i--)
    {
        *pbDest += tmp*(*(pbSrc+i)-'0');
        tmp = tmp*10;
    }
}
u16 DectoStr (u8 *pSrc, u16 SrcLen, u8 *pObj)
{
    u16 i=0;
    for(i=0;    i<SrcLen;   i++)
    {
        sprintf((char *)(pObj + i * 2), "%02d", *(pSrc + i));
    }
    *(pObj + i * 2) = '\0';
    return  (i * 2);
}

浮点

//m^n函数
//返回值:m^n次方.
u32 NMEA_Pow(u8 m,u8 n)
{
    u32 result=1;    
    while(n--)result*=m;    
    return result;
}
//str转换为数字,以','或者'*'结束
//buf:数字存储区
//dx:小数点位数,返回给调用函数
//返回值:转换后的数值
int NMEA_Str2num(u8 *buf,u8*dx)
{
    u8 *p=buf;
    u32 ires=0,fres=0;
    u8 ilen=0,flen=0,i;
    u8 mask=0;
    int res;
    while(1) //得到整数和小数的长度
    {
        if(*p=='-'){mask|=0X02;p++;}//是负数
        if(*p==','||(*p=='*'))break;//遇到结束了
        if(*p=='.'){mask|=0X01;p++;}//遇到小数点了
        else if(*p>'9'||(*p<'0'))   //有非法字符
        {   
            ilen=0;
            flen=0;
            break;
        }   
        if(mask&0X01)flen++;
        else ilen++;
        p++;
    }
    if(mask&0X02)buf++; //去掉负号
    for(i=0;i<ilen;i++) //得到整数部分数据
    {  
        ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-'0');
    }
    if(flen>5)flen=5;   //最多取5位小数
    *dx=flen;           //小数点位数
    for(i=0;i<flen;i++) //得到小数部分数据
    {  
        fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0');
    } 
    res=ires*NMEA_Pow(10,flen)+fres;
    if(mask&0X02)res=-res;         
    return res;
} 
#include <stdio.h>
#include <stdlib.h>
char *FloatToString(double d,char *str)
{
  char str1[40];
  int j = 0,k,i;
  i = (int)d;//浮点数的整数部分
  while(i > 0)
  {
  str1[j++] = i % 10 + '0';
  i = i / 10;
  }
  for(k = 0;k < j;k++)
  {
  str[k] = str1[j-1-k];//被提取的整数部分正序存放到另一个数组
  }
  str[j++] = '.';
  d = d - (int)d;//小数部分提取
  for(i = 0;i < 10;i++)
  {
  d = d*10;
  str[j++] = (int)d + '0';
  d = d - (int)d;
  }
  while(str[--j] == '0');
  str[++j] = '\0';
  return str;
}
int main(int argc, char **argv)
{
  double d = 365.80323;
  char str[20];
  FloatToString(d,str);
  printf("%s\n",str);
  return 0;
}

6 16进制和字符串转化

void StrToHex(char *pbDest, char *pbSrc, int nLen)
{
  char h1,h2;
  char s1,s2;
  int i;
    for (i=0; i<nLen/2; i++)
    {
        h1 = pbSrc[2*i];
        h2 = pbSrc[2*i+1];
        s1 = toupper(h1) - 0x30; //toupper 转换为大写字母
        if (s1 > 9)
            s1 -= 7;
        s2 = toupper(h2) - 0x30;
        if (s2 > 9)
            s2 -= 7;
        pbDest[i] = s1*16 + s2;
    }
}
void StrToHex(char *pbDest, char *pbSrc, int nLen)
{
  char h1,h2;
  char s1,s2;
  int i;
    for (i=0; i<nLen/2; i++)
    {
        h1 = pbSrc[2*i];
        h2 = pbSrc[2*i+1];
        s1 = toupper(h1) - 0x30; //toupper 转换为大写字母
        if (s1 > 9)
            s1 -= 7;
        s2 = toupper(h2) - 0x30;
        if (s2 > 9)
            s2 -= 7;
        pbDest[i] = s1*16 + s2;
    }
}
u16 Hex2StringArray (u8 *pSrc,  u16 SrcLen, u8 *pObj)
{
    u16 i=0;
    for(i=0;    i<SrcLen;   i++)
    {
        sprintf((char *)(pObj + i * 2), "%02X", *(pSrc + i));
    }
    *(pObj + i * 2) = '\0';
    return  (i * 2);
}

7 数据回写

#include < stdlib.h>
#include < stdio.h >
#include < errno.h>
#include < sys/stat.h>
#include < unistd.h>
#define BUFF_SIZE 4096
int create_test_file(char* file_path)
{
FILE* pf = fopen(file_path, "w");
if (pf == 0)
{
return 0;
}
int i = 10000, j = 0;
for (; i > 0; --i)
{
    for (j = 0; j < 10; ++j)
    {
        fprintf(pf, "%d", j);
    }
    fprintf(pf, "%s", "\n");
}
fflush(pf);
fclose(pf);
return 1;
}
size_t get_file_size(const char *path)
{
size_t fsize = -1;
struct stat stbuff;
if (stat(path, &stbuff) < 0)
{
return fsize;
}
else
{
fsize = stbuff.st_size;
}
return fsize;
}
void reverse_buff(char* buff, int buflen)
{
int i = 0, j = buflen / 2, k = buflen % 2;
char c;
for ( ; i < j; ++i)
{
c = buff[i];
buff[i] = buff[buflen - i - 1];
buff[buflen - i - 1] = c;
}
}
void change_buff_block(FILE* pf, size_t fsize, int left_block, int left_size, int right_size)
{
char buff1[BUFF_SIZE];
char buff2[BUFF_SIZE];
size_t rs, ws;
fseek(pf, BUFF_SIZE * left_block, SEEK_SET);
rs = fread(buff1, left_size, 1, pf);
reverse_buff(buff1, left_size);
if (right_size > 0)
{
    fseek(pf, fsize - BUFF_SIZE * left_block - right_size, SEEK_SET);
    rs = fread(buff2, right_size, 1, pf);
    reverse_buff(buff2, right_size);
    fseek(pf, BUFF_SIZE * left_block, SEEK_SET);
    ws = fwrite(buff2, right_size, 1, pf);
    fseek(pf, fsize - BUFF_SIZE * (left_block + 1), SEEK_SET);
    ws = fwrite(buff1, left_size, 1, pf);
}
else
{
    fseek(pf, BUFF_SIZE * left_block, SEEK_SET);
    ws = fwrite(buff1, left_size, 1, pf);
}
}
int main(int argc, char* argv[])
{
if (argc < 1)
{
printf("please pass test file as first arg!");
return -1;
}
char* file = argv[0];
if (argc > 1 && argv[1][0] == 'c' && !create_test_file(file))// if create test file
{
printf("create test file failed!");
return -1;
}
size_t fsize = get_file_size(file);
if (fsize <= 0)
{
    printf("file not exists or is empty!");
    return -1;
}
size_t remsize = fsize % BUFF_SIZE;
int buff_cnt = fsize / BUFF_SIZE + (remsize > 0 ? 1 : 0);
int inv_cnt = buff_cnt / 2;
FILE* pf = fopen(file, "r+");
if (pf == 0)
{
    printf("cannot open file!");
    return -1;
}
int i, j;
for (i = 0; i < inv_cnt - 1; ++i)
{
    change_buff_block(pf, fsize, i, BUFF_SIZE, BUFF_SIZE);
}
if (buff_cnt % 2 > 0)
{
    change_buff_block(pf, fsize, i, BUFF_SIZE, BUFF_SIZE);
    change_buff_block(pf, fsize, ++i, remsize, 0);  
}
else if (remsize > 0)
{
    change_buff_block(pf, fsize, i, BUFF_SIZE, remsize);
}
else
{
    change_buff_block(pf, fsize, i, BUFF_SIZE, BUFF_SIZE);
}
fflush(pf);
fclose(pf);
printf("test ok!");
return 0;
}
相关文章
|
8月前
|
存储 安全 C++
C++ 用户输入与数据类型详解:建立基本计算器及变量类型
了解C++的用户输入和数据类型。使用`cin`从键盘读取数据,如在简单计算器示例中获取两个数字并求和。C++的数据类型包括:`int`(整数)、`float`(浮点数,约6-7位小数)、`double`(更精确的浮点数,约15位小数)、`bool`(布尔值,true或false)、`char`(单个字符)和`string`(文本字符串)。每种类型都有特定的存储大小和用途。在处理浮点数时,`double`通常更安全。字符串需要包含`&lt;string&gt;`库。更多内容可关注微信公众号`Let us Coding`获取。
91 0
|
8月前
|
存储 程序员 C++
C++数据类型
C++数据类型
57 2
|
7月前
|
Java API C++
Java JNI开发时常用数据类型与C++中数据类型转换
Java JNI开发时常用数据类型与C++中数据类型转换
259 0
|
4月前
|
存储 Linux C语言
【C++基础】数据类型详解
这篇文章详细介绍了C++中各种基本数据类型,包括整型、浮点型、字符型、字符串型和布尔型,以及它们的使用方式和范围。
40 4
|
5月前
|
C++
c++学习笔记01 基本知识与数据类型
C++学习笔记,涵盖了C++中的常量定义、数据类型、变量内存大小计算、基本数据类型(整型、实型、字符型、字符串型、布尔型)以及转义字符的使用。
50 4
|
7月前
|
存储 C++ 容器
C++一分钟之-变量与数据类型入门
【6月更文挑战第18天】**C++编程基础:变量与数据类型概览** 了解变量(存储数据的容器)和数据类型是编程入门的关键。声明变量如`int age = 25;`,注意初始化和类型匹配。基本数据类型包括整型(int等)、浮点型(float、double)、字符型(char)和布尔型(bool)。理解类型范围和精度,使用字面量后缀增强可读性。深入学习数组、指针、结构体和类,以及动态内存管理,避免数组越界和内存泄漏。不断实践以巩固理论知识。
46 1
|
7月前
|
数据安全/隐私保护 C++
C++ 中的类是一种用户定义的数据类型,用于表示具有相似特征和行为的对象的模板。
C++ 中的类是一种用户定义的数据类型,用于表示具有相似特征和行为的对象的模板。
|
6月前
|
存储 编译器 C++
|
7月前
|
C语言 C++
技术经验分享:c++中的数据类型转换
技术经验分享:c++中的数据类型转换
36 0
|
8月前
|
存储 安全 编译器
C++数据类型与变量:深入理解与应用
C++数据类型与变量:深入理解与应用