以前一直用C++,现在转向C。经历了一开始的别扭之后,越发感觉到C的牛逼。
几个常用的函数:fscanf,fprintf,fgets,strncpy, memcpy , memset ,strlen,atoi。
C里面一个原则是:不用没有数量限制的函数。比如:strcpy要求开发者自己保证复制的两者能满足要求,用strncpy代替。strncpy(char*dest,char*src,size_t size)
用C编写模版其实特别简单。在C里面,用的最多的指针是void*,这是一个桥梁。同时还有一个是unsigned char*指针,这个用来申请空间。
下面贴一段我用C写的List。
#include <stdio.h>
#include <string.h>
typedef struct Node{
char str[24];
int iNum;
}Node; //for test
class cList{
private:
typedef struct _list_node{
unsigned char*str;
struct _list_node*pNext;
}cListNode;
cListNode* pHead;
cListNode* pTail;
cListNode* pTravel;
public:
cList(){
pHead = NULL;
pTail = NULL;
pTravel = NULL;
}
~cList(){
pHead = NULL;
pTail = NULL;
pTravel = NULL;
}
int init(){
pHead = new cListNode();
if(NULL == pHead){
fprintf(stderr,"memory lost!\n");
return -1;
}
pHead->pNext = NULL;
pTail = pHead;
pTravel = pHead->pNext;
return 0;
}
int uninit(){
while(pHead){
pTravel = pHead->pNext;
delete pHead;
pHead = pTravel;
}
pHead = NULL;
pTravel = NULL;
pTail = NULL;
}
int insert(unsigned char* src,size_t size){
if(NULL == src|| 0 >= size){
return -1;
}
if(NULL == pHead){
fprintf(stderr,"please init first!\n");
return -1;
}
cListNode* pCur = new cListNode();
pCur->str = new unsigned char[size+1];
memcpy(pCur->str,src,size);
pCur->str[size+1] = 0;
pCur->pNext = NULL;
pTail->pNext = pCur;
pTail = pCur;
pTravel = pHead->pNext;
return 0;
}
int travel(unsigned char*dest,size_t size){
if(NULL == pHead){
fprintf(stderr,"please init first!\n");
return -1;
}
if(pTravel){
memcpy(dest,pTravel->str,size);
dest[size+1] = 0;
pTravel = pTravel->pNext;
return 0;
}
pTravel = pHead->pNext;
return -1;
}
};
int main(){
printf("%d\n",sizeof(Node));
Node m_t;
char* s = "hello!";
strncpy(m_t.str,s,strlen(s));
m_t.iNum = 0;
unsigned char ucStr[128];
memcpy(ucStr,&m_t,sizeof(m_t));
ucStr[sizeof(m_t)+1] = 0;
//test
cList m_c;
m_c.init();
int i = 0;
while(i < 10){
m_c.insert((unsigned char*)&m_t,sizeof(m_t));
++i;
}
Node res;
while(-1 != m_c.travel((unsigned char*)&res,sizeof(Node))){
printf("%s\t%d\n",res.str,res.iNum);
}
}
其中,insert和travel都要求传入节点的大小。这里所有的空间都是通过new unsigned char[size+1]的方式得到的,通过强制转换指针来取得结构体的内容。由此也可以写一个比较大小的模版,看起来有些怪,但事实上C++就是这么做的。
#include <stdio.h>
#include <string.h>
int comp(unsigned char*val1,unsigned char*val2,char*STYPE = "INT"){
if(NULL == val1 || NULL == val2){
fprintf(stderr,"val1 or val2 is NULL\n");
return -2;
}
int iType = 0;
char* sType[2] = {"INT","FLOAT"};
for(int i = 0; i < 2; ++i){
if(strcmp(sType[i],STYPE) == 0){
iType = i+1;
break;
}
}
enum TYPE{
INT = 1,
FLOAT
};
switch (iType){
case INT:
return *(int*)val1-*(int*)val2;
break;
case FLOAT:
return *(float*)val1-*(float*)val2;
break;
default:
fprintf(stderr,"no this type");
}
return -3;
}
int main(){
// int x = 234;
// int y = 245;
float x = 23.3456;
float y = 139234.23;
int ret = comp((unsigned char*)&x,(unsigned char*)&y,"FLOAT");
fprintf(stderr,"%d\n",ret);
}
C++的模版,就是在实例化的时候,生成对应的C代码,这里显示的给写出来了。