以下内容源于网络资料的学习整理,如有侵权,请告知删除。
目录
1、将字符串反转
2、数字翻转和回文判断
3、大小端问题
(1)判断大小端
(2)大小端转换
4、实现函数memcpy(), strcpy(), strcmp(), strcat()
5、实现最简单的hello world字符设备驱动
6、设计函数 int atoi(char *s),void itoa(int n, char s[])
7、链表操作(单链表的插入、删除节点、遍历、反转)
1、将字符串反转
void reserverString(char str[])
{char tmp;int i, j;for (i = 0, j = strlen(str) - 1; i < j; i++, j--){tmp = str[i];str[i] = str[j];str[j] = tmp;}
}char* reserverString1(char* str)
{char* start = str;char* end = str + strlen(str) - 1;char tmp;if (NULL != str){do{tmp = *start;*start++ = *end;*end-- = tmp;} while (start<end);}return str;
}
2、数字翻转和回文判断
3、大小端问题
(1)判断大小端
方法一:
int main(void)
{int a = 0x1234;char b = *((char*)&a);if (b == 0x12)printf("BIGEND\n");if (b == 0x34)printf("littleEND\n");system("PAUSE");return 0;
}
方法二:用联合体
(2)大小端转换
//对于字数据16bit
#define BIG2LITTLE(A) ((((A)&0xff00)>>8) | (((A)&0x00ff)<<8)) //对于双字数据32bit
#define BIG2LITTLE(A) (((A)&0xff000000)>>24) | (((A)&0x000000ff)<<24) | (((A)&0x0000ff00)<<8) | (((A)&0x00ff00)>>8))
4、实现函数memcpy(), strcpy(), strcmp(), strcat()
(1)函数原型 :void *memcpy(void *dest, const void *src, size_t n);
功能:从源src所指的内存地址的起始位置开始,拷贝n个字节到目标dest所指的内存地址的起始位置中,函数返回dest的值。
void *memcpy(void *dest, const void *src, size_t n)
{if (NULL == dest || NULL == src)return NULL;char* tmp = (char*)dest;const char* s = (const char*)src;//这里注意下while (n--){*tmp++ = *s++;}return dest;
}
(2)函数原型 :void strcpy (char *dest,const char*src);
功能:将src拷贝到dest中
void strcpy(char *dest, const char*src)
{while(*dest++=*src++){}
}
(3)函数原型 :int strcmp(const char *s,const char * t);
功能:比较字符串s和t,并且根据s按照字典顺序小于,等于或大于t的结果分别返回负整数,0,正整数。
int strcmp(const char *s, const char * t)
{for (; *s == *t; s++, t++)//注意for循环,能循环下去的条件的两者元素对应相等,一旦不相等立即退出if (*s == '\0')return 0;//表示相等return *s - *t;
}
(4)函数原型 :char *strcat(char *dest,char *src);
功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0',返回指向dest的指针
char* strcat(char *dest,const char *src)
{char* tmp = dest;assert((NULL != dest) && (NULL != src));while (*tmp){tmp++;}//循环结束时,指针指向字符'\0',后面会覆盖while (*tmp++ = *src++) {}return dest;
}
5、实现最简单的hello world字符设备驱动
//1、头文件的包含
#include <linux/init.h>
#include <linux/module.h>//许可的声明
MODULE_LICENSE("Dual BSD/GPL");//3、函数注意static、返回值、printk、KERN
static int hello_init(void)
{printk(KERN_ALERT "Hello World!\n");return 0;
}
static void hello_exit(void)
{printk(KERN_ALERT "Goodbye, cruel world\n");
}
//4、注意这两个宏函数的使用
module_init(hello_init);
module_exit(hello_exit);
6、设计函数 int atoi(char *s),void itoa(int n, char s[])
(1)int atoi(char *s)
描述:把字符串转换成整型数的一个函数。int atoi(const char *nptr) 函数会扫描参数 nptr字符串,跳过前面的空白字符(例如空格,tab缩进)等,可以通过isspace( )函数来检测),直到遇上数字或正负符号才开始做转换,而在遇到非数字或字符串结束符('\0')才结束转换,并将结果返回。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回0。特别注意,该函数要求被转换的字符串是按十进制数理解的。
int atoi(char s[])
{int i, n, sign;for (i = 0; isspace(s[i]); i++); /*跳过空白符:空格时会一直循环,直到遇到不是空格*/sign = (s[i] == '-') ? -1 : 1;//遇到的如果不是-号,比如是数字,则说明不是负数if (s[i] == '+' || s[i] == '-') /* 跳过符号 */i++;for (n = 0; isdigit(s[i]); i++)n = 10 * n + (s[i] - '0');return sign * n;
}//注意判断空格、是否是数字的函数,你懂写吗?
(2)void itoa(int n, char s[])
功能:将整型数字转换为字符串
void itoa(int n, char s[])
{int i, sign;if ((sign = n) < 0) //记录符号n = -n; //使n成为正数i = 0;do { //以反序生成数字 //假设n=987654s[i++] = n % 10 + '0'; //n % 10 + '0'表示数字对应的字符,比如第一次的数字是4,变成字符4,是4+'0'} while ((n /= 10) > 0); //此时n变成了98765if (sign < 0)s[i++] = '-';s[i] = '\0';reverse(s);
}
7、链表操作(单链表的插入、删除节点、遍历、反转)
https://blog.csdn.net/oqqHuTu12345678/article/details/78899439
#include <stdio.h>
#include <string.h>
#include <stdlib.h>typedef struct node
{int data;struct node* next;
}Node;/*********************************************************************
1、函数功能:将链表反转
2、实现方法:遍历+头插入,即每遍历一个元素,立即将该元素头插入
3、函数返回:反转后链表头结点的指针
4、之前遇到的、有头结点的链表,头或尾插入一个数都很简单;
5、现在多个数连续插入稍微难处理,而且这主要运用在反转链表中。
2018.925 xjh
*********************************************************************/Node* reserverLinklist(Node* PH)
{Node* p = PH->next;//p表示当前节点指针Node* pnext = NULL;//pnext表示当前节点的下一个节点指针Node* head = NULL;//用来实现头插入的临时变量//特殊情况处理:当链表没有有效节点或者只有一个有效节点时,逆序不用做任何操作if ((NULL == p) || (NULL == p->next))return PH;while (NULL!=p)//如果当前节点不为空{pnext = p->next;//后面因为新链表头插入,破坏了p->next,因此先要备份p->next,否则丢失原链表的信息//新链表头插入p->next = head;head = p;//恢复p,以便进入到下一个元素(p没有改变,但p->next改变了,因此不能直接p=p->next)p = pnext;}//这个结束时,p为NULL,head指向原链表的最后一个元素,该元素在新链表中是第一个元素,下面在该元素前添加头结点PH->next = head;return PH;
}struct node * create_node(int data)
{struct node *p = (struct node *)malloc(sizeof(struct node));if (NULL == p){printf("malloc error.\n");return NULL;}p->data = data;p->next = NULL;return p;
}void insert_head(Node *pH, Node *newNode)
{newNode->next = pH->next;pH->next = newNode;
}void traverse(Node* pH)
{struct node *p = pH;printf("-----------开始遍历-----------\n");while (NULL != p->next) {p = p->next;printf("node data: %d.\n", p->data);}printf("-----------遍历结束-----------\n");
}int main(void)
{Node *pHeader0 = create_node(0);//创建头结点Node *pHeader1 = NULL;insert_head(pHeader0, create_node(11));//11,12,13是所创建的节点数据,这里采用头插法。insert_head(pHeader0, create_node(12));insert_head(pHeader0, create_node(13));//此步过后,数据应该为0,13,12,11traverse(pHeader0);//打印13,12,11pHeader1 = reserverLinklist(pHeader0);traverse(pHeader1);//打印11,12,13system("PAUSE");return 0;
}