C语言中一些比较基础而又重要的知识

1、字符串截取

对于字符串char *tar = "Mine_tar1_tar2",想要获取tar1tar2,可使用strstrstrchr获取目标字符()的位置,再利用strcpy,第三个参数设置截取长度。

另外strncmp的第三个参数表示比较俩字符串前n

char *des; char sTar1[65] = {0}; char sTar2[65] = {0}; //必须要初始化终止位,否则拷贝后会出现乱码 des = strstr(user_data_info + 4, "_"); memcpy(sTar1, user_data_info + USER_DEFINED_LEN, des - user_data_info - 4); memcpy(sTar2, des + 1, 65);   

2、初始化及内存分配

很多字符串在用strcpy拷贝时会报错或者直接赋值时会出现乱码,都是因为没有初始化。

char *str = (char *)malloc(sizeof(char));

memset(str,0,sizeof(char));即可

有时在编译时并不知道数组的长度,可以这样动态分配数组

size = get_size(); int *p = new int[n]; for(int *q=p;q!=p+n;++q) ... delete []p;

一个自定义结构体的初始化

MYSTUCT mystr;

memset(&mystr,0,sizeof(mystr));

和下面皆可

MYSTUCT *mystr;

memset(mystr,0,sizeof(*mystr));

如果是二维的数组,在初始化时能否直接将声明的二维数组的数组名传递给一个指针呢?编译后就会发现是有问题的,一维数组的数组名即为指向该数组的指针,该指针值保存了数组存放在内存中的一块连续区域的起始地址,所以数组的下标就表示了这片内存区域的某存储区相对于起始地址的偏移量;而二维数组在概念上远比一维数组复杂,或者说二维数组以一种晦涩的方式构建在一维数组之上。

之前在C++博客里看见过一篇文章,记了一点笔记如下:

   事实上,计算机系统的多维数组其实最终还是以一维数组的形式实现的。就N x M的二维数组来讲,设其数组名为array。指针array指向一个数组,该数组存放的是一系列指针,这些指针分别指向相应的一维数组,而这些数组中存放的才是我们的数据。

array -> [一维数组指针1] ->   [ 一维数组,M]

         [一维数组指针2] ->   [ 一维数组,M]

         ……           ……

         [一维数组指针N] ->   [ 一维数组,M]

由此可见array是第i个指针变量地址,array[j]则表示相对于第i个指针变量偏移 j*sizeof(数组类型)

系统通过这种机制访问了该N*M维数组的第i行,第j列的内容。

 

所以,对于一个二维数组MYSTUCT mystr[N][M],就需要用数组指针或二维指针来表示了。

初始化的方法有两种

MYSTRUCT **des = malloc(N*sizeof(MYSTRUCT*));

for(int i = 0;i<N;i++)

   des[i] = malloc(M*sizeof(MYSTRUCT));

下面这个例子是两个一维指针对二维数组的操作

void double_div() { int score[3][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}}; int *p1,*p2; int i; for(p1=*score;p1<=*(score+2);p1=p1+4)/* score+i终究还是地址 */ { for(p2=p1;p2<p1+4;p2++) { if(*p2<60) { for(i=0;i<4;i++) { printf("%d ",*(p1+i)); } printf("/n"); } } } }   

3、内存拷贝

利用函数memcpy,对象指针必须初始化。另外,通过内存拷贝对数据类型没有约束,这也是后面说的CStringchar*能用CT2A宏的方法,如果用strcpy或直接=赋值都无法达到效果。

float a = 3.12; float b = 0.0; void *data; data = malloc(sizeof(float));//4 memcpy(data,&a,sizeof(float)); memcpy(&b,data,sizeof(float));   

4、比特取高低位

通常在通讯中会碰到将帧长度什么的分成高低位两个字节,先填低位,读则先读高位。

BYTE Frame[500];

memset(Frame,0,sizeof(Frame)); int a; Frame[0] = (unsigned char)a; Frame[1] = a>>8; 反之: a = Frame[1]; a <<= 8; a+=Frame[0];   

5、类型转换

  整形转化成字符串,itoa(ltoa,第三个参数为进制)fcvt(用于浮点型数据,后两个参数返回),对于非COM类型的数据,用sprintf完成转换CString是动态的TCHAR数组,BSTR是一种专有格式的字符串,而char* 是指向ANSI字符数组的指针,其中每个字符占据8位(有效数据是除掉最高位的其他7位),它保持了与传统的C,C++的兼容。

   对于常见的LPCTSTR等类型,LP的含义是长指针(long pointer)LPSTR是一个指向以‘/0结尾的ANSI字符数组的指针,与char*可以互换使用,在win32中较多地使用LPSTR

LPCSTR中增加的‘C’的含义是“CONSTANT(常量),表明这种数据类型的实例不能被使用它的API函数改变,除此之外,它与LPSTR是等同的。

T是什么东西呢,我们知道TCHAR在采用Unicode方式编译时是wchar_t,在普通时编译成char

为了满足程序代码国际化的需要,业界推出了Unicode标准,它提供了一种简单和一致的表达字符串的方法,所有字符中的字节都是16位的值,其数量也可以满足差不多世界上所有书面语言字符的编码需求,开发程序时使用Unicode(类型为wchar_t)是一种被鼓励的做法。LPWSTRLPCWSTR由此产生,它们的含义类似于LPSTRLPCSTR,只是字符数据是16位的wchar_t而不是char。所以,在C++中,如果定义_UNICODE,声明为:typedef wchar_t TCHAR;如果没有定义_UNICODE,则声明为:typedef char TCHAR;LPTSTRLPCTSTR中的含义就是每个字符是这样的TCHAR

给出下面这两个例子,相信再转换成LPSTRTCHAR等类型就简单多了吧,O(_)O~

 LPCTSTR: #ifdef _UNICODE typedef const wchar_t * LPCTSTR; #else typedef const char * LPCTSTR; #endif

通用转换 float a = 1.124568F; char *s; s = malloc(200); sprintf(s,"%f",a); CString转char* CString str = "cstring"; char *chr; int len = str.GetLength(); chr = (char*)malloc((2*len+1)*sizeof(char)); memset(chr,0,2*len+1); strcpy(chr,CT2A(str));

VC6.0,可以通过GetBuffer转换,但VS2008中不行,memcpy(chr,str.GetBuffer(len),(len*2+1)*sizeof(char))chr的值为c,不懂...

 

6、输出结果到文件

这个功能在需要提取一些数据时还蛮好用的,直接用例子更直接:

ofstream out("C://out.txt");

streambuf *stream = cout.rdbuf();

cout.rdbuf(ou.rdbuf());

cout<<要输出的东西(放进循环也可以)<<endl;

 

你可能感兴趣的:(C语言中一些比较基础而又重要的知识)