1.memcpy函数

memcpy 函数用于 把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域);拷贝多少个?有一个size变量控制拷贝的字节数;

函数原型:void *memcpy(void *dest, void *src, unsigned int count);

用法:可以拷贝任何类型的对象,因为函数的参数类型是void*(未定义类型指针),也就是说传进去的实参可以是int*,short*,char*等等,但是由于函数拷贝的过程是一个字节一个字节的拷贝的,所以实际操作的时候要把void*强制转化为char*,这样在指针加的时候才会保证每次加一个字节;

  1. /********memcpy()函数原型为:void* memcpy(void* dest, const void* src, size_t n); 返回指向dest的空类型指针*********/
  2. //返回void* 类型的原因,是为了使用链式表达,即strlen((char*)(memcpy(dest,src,n)),这样可以直接计算dest的长度,是程序代码更简洁
  3. /****注意void* 指针的使用,即该函数允许传入任何类型的指针数据****/
  4. void* memcpy(void *dest,const void *src, size_t n)
  5. {
  6. assert((dest != NULL) && (src != NULL));
  7. char *dest_t = (char*)dest; //转换成字符型一个个复制拷贝,由于函数拷贝的过程是一个字节一个字节的拷贝的,
  8. //所以实际操作的时候要把void*强制转化为char*,
  9. char *src_f = (char*)src; //这样在指针加的时候才会保证每次加一个字节
  10. while (n-- > )
  11. {
  12. *(dest_t++) = *(src_f++);
  13. }
  14. return dest;//void* 一定要返回一个值(指针),这个和void不太一样!函数返回指向dest的指针
  15.  
  16. }

注1:与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。

2:如果目标数组dest本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。

  1. //memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;
  2.  
  3.   char a[100], b[50];
  4.  
  5.   memcpy(b, a,sizeof(b)); //注意如用sizeof(a),会造成b的内存地址溢出。
  6.  
  7.   strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:
  8.  
  9.   char a[100], b[50];
  10.  
  11. strcpy(a,b);

2.strcpy函数

写法一、

  1. 1 char * strcpy( char *strDest, const char *strSrc )
  2. 2 {
  3. 3 assert( (strDest != NULL) && (strSrc != NULL) );//检测输入指针是否能访问
  4. 4 char *address = strDest;
  5. 5 while( (*strDest++ = * strSrc++) != \0 ); //复制字符串
  6. 6 return address;//返回指针
  7. 7 }

写法二、

  1. /********strcpy()函数原型为:char *strcpy(char* dest, const char *src); 返回指向dest的指针*********/
  2. //返回char* 类型的原因,是为了使用链式表达,即strlen(strcpy(dest,src)),这样可以直接计算dest的长度,是程序代码更简洁
  3.  
  4. char* strcpy(char *dest, char *src)
  5. {
  6. if(dest == NULL || src == NULL)
  7. return NULL;
  8. char *res = dest;//保存原始dst的首地址
  9. while(*src != '\0')
  10. {
  11. *dest = *src;
  12. dest++;
  13. src++;
  14. }
  15. *dest = '\0';
  16. return res;
  17. }

3.strcat函数

功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')。

说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。

  1. #include <stdio.h>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. char* strcat(char *dest, char *src)
  7. {
  8. if (dest == NULL)
  9. return NULL;
  10. if (src == NULL)
  11. return dest;
  12. char *head = dest;
  13. while (*dest != '\0')
  14. dest++;
  15. while (*src != '\0')
  16. {
  17. *dest = *src;
  18. dest++;
  19. src++;
  20. }
  21. *dest = '\0';
  22. return head;
  23. }
  24.  
  25. int main()
  26. {
  27. char dest[] = "nihao";
  28. char src[] = "zhouyang";
  29. char *res = strcat(dest, src);
  30. cout << dest << endl;
  31. system("pause");
  32. return 0;
  33. }

4.strcmp函数

功能:比较两个字符串大小。

实际上是对字符的ASCII码进行比较,实现原理如下:首先比较两个串的第一个字符,若不相等,则停止比较并得出两个ASCII码大小比较的结果;如果相等就接着比较第二个字符然后第三个字符等等。无论两个字符串是什么样,strcmp函数最多比较到其中一个字符串遇到结束符'/0'为止,就能得出结果。

返回结果:①str1小于str2,返回负值或者-1(VC返回-1);②str1等于str2,返回0;③str1大于str2,返回正值或者1(VC返回1);

  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <assert.h>
  4.  
  5. using namespace std;
  6.  
  7. /****strcmp原型: int strcmp(const char *str1, const char *str2)*****/
  8. int strcmp(const char *str1, const char *str2)
  9. {
  10. assert((str1 != NULL) && (str2 != NULL));
  11. while ((*str1 != '\0') && (*str2 != '\0'))
  12. {
  13. if (*str1 == *str2)
  14. {
  15. str1++;
  16. str2++;
  17. }
  18. else
  19. {
  20. if (*str1 > *str2)
  21. return 1;
  22. else
  23. return -1;
  24. }
  25. }
  26. if (*str1 == '\0' && *str2 == '\0')
  27. return 0;
  28. else if (*str1 == '\0' && *str2 != '\0')
  29. return -1;
  30. else if (*str1 != '\0' && *str2 == '\0')
  31. return 1;
  32. }
  33.  
  34. int main()
  35. {
  36. char *str1 = "78";
  37. char *str2 = "789";
  38. int res = strcmp(str1, str2);
  39. cout << res << endl;
  40. system("pause");
  41. return 0;
  42. }

5.strlen函数

功能:返回字符串的长度。

  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <assert.h>
  4.  
  5. using namespace std;
  6.  
  7. /********strlen()函数原型为:int strlen(const char *src); 返回字符串的长度*********/
  8. size_t strlen(const char *str)
  9. {
  10. assert(str != NULL);
  11. int num = 0;
  12. while(*str != '\0')
  13. {
  14. str++;
  15. num++;
  16. }
  17. return num;
  18. }
  19.  
  20. int main()
  21. {
  22. char *str = "123456";
  23. int temp = strlen(str);
  24. cout << temp << endl;
  25. return 0;
  26. }

6.strncpy

功能:将字符串src中最多n个字符复制到字符数组dest中(它并不像strcpy一样遇到NULL才停止复制,而是等凑够n个字符才开始复制),返回指向dest的指针。

要求:如果n > dest串长度,dest栈空间溢出产生崩溃异常。该函数注意的地方和strcpy类似,但是n值需特别注意。

  1. #include <iostream>
  2. #include <stdio.h>
  3.  
  4. using namespace std;
  5.  
  6. /***string.h,char *strncpy(char *dest, const char *src, size_t n),
  7. 把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。**/
  8. char* mystrncpy(char *dest, const char *src, size_t n)
  9. {
  10. if (dest == NULL || src == NULL || n < 0)
  11. return NULL;
  12. char *res = dest;
  13. while (n--)
  14. {
  15. *dest = *src;
  16. dest++;
  17. src++;
  18. }
  19. *dest = '\0';
  20. return res;
  21. }
  22.  
  23. int main()
  24. {
  25. char *src = "hello world";
  26. char c[10];
  27. char *res = mystrncpy(c, src, 7);
  28. cout << res << endl;
  29. system("pause");
  30. return 0;
  31.  
  32. }

7.strstr函数

功能:给出字符串str1, str2,判断str2是否为str1的子字符串,如果是,返回str2在str1中对应的起始地址。

  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <assert.h>
  4.  
  5. using namespace std;
  6.  
  7. /****
  8. 函数原型:
  9. extern char *strstr(const char *str1, const char *str2);
  10.  
  11. str1: 被查找目标 string expression to search.
  12. str2: 要查找对象 The string expression to find.
  13. 返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
  14. ****/
  15.  
  16. const char* strstr(const char *str1, const char *str2)
  17. {
  18. if (str1== NULL || str2 == NULL)
  19. return NULL;
  20. const char *temp = str1;
  21. const char *res = str2;while (*str1 != '\0')
  22. {
  23. temp = str1;
  24. res = str2;
  25. while (*temp== *res){
  26. temp++;
  27. res++;
  28. }
  29. if (*res == '\0')return str1;
  30. str1++;
  31.  
  32. }
  33. return NULL;
  34.  
  35. }
  36. int main()
  37. {
  38. char *src = "1234567";
  39. char *dest = "345";
  40. const char *res = strstr(src, dest);
  41. cout << res<< endl;//cout<<重载了,会直接输出字符串内容而不是地址
  42. system("pause");
  43. return 0;
  44. }

8.printf()

写法一

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. /*
  4. * 函数名: myPrintf
  5. * 函数功能: 打印格式字符串
  6. * 参数: 1. 包含格式符的字符串地址 2.可变参
  7. * 返回值: 无
  8. */
  9. void myPrintf(char *s, ...)
  10. {
  11. int i = ;
  12.  
  13. /* 可变参第一步 */
  14. va_list va_ptr;
  15.  
  16. /* 可变参第二部 */
  17. va_start(va_ptr, s);
  18.  
  19. /* 循环打印所有格式字符串 */
  20. while (s[i] != '\0')
  21. {
  22. /* 普通字符正常打印 */
  23. if (s[i] != '%')
  24. {
  25. putchar(s[i++]);
  26. continue;
  27. }
  28.  
  29. /* 格式字符特殊处理 */
  30. switch (s[++i]) // i先++是为了取'%'后面的格式字符
  31. {
  32. /* 根据格式字符的不同来调用不同的函数 */
  33. case 'd': printDeci(va_arg(va_ptr,int));
  34. break;
  35. case 'o': printOct(va_arg(va_ptr,unsigned int));
  36. break;
  37. case 'x': printHex(va_arg(va_ptr,unsigned int));
  38. break;
  39. case 'c': putchar(va_arg(va_ptr,int));
  40. break;
  41. case 'p': printAddr(va_arg(va_ptr,unsigned long));
  42. break;
  43. case 'f': printFloat(va_arg(va_ptr,double));
  44. break;
  45. case 's': printStr(va_arg(va_ptr,char *));
  46. break;
  47. default : break;
  48. }
  49.  
  50. i++; // 下一个字符
  51. }
  52.  
  53. /* 可变参最后一步 */
  54. va_end(va_ptr);
  55. }

写法二、

  1. /*(转载)
  2. * A simple printf function. Only support the following format:
  3. * Code Format
  4. * %c character
  5. * %d signed integers
  6. * %i signed integers
  7. * %s a string of characters
  8. * %o octal
  9. * %x unsigned hexadecimal
  10. */
  11. int my_printf( const char* format, ...)
  12. {
  13. va_list arg;
  14. int done = ;
  15.  
  16. va_start (arg, format);
  17.  
  18. while( *format != '\0')
  19. {
  20. if( *format == '%')
  21. {
  22. if( *(format+) == 'c' )
  23. {
  24. char c = (char)va_arg(arg, int);
  25. putc(c, stdout);
  26. } else if( *(format+) == 'd' || *(format+) == 'i')
  27. {
  28. char store[];
  29. int i = va_arg(arg, int);
  30. char* str = store;
  31. itoa(i, store, );
  32. while( *str != '\0') putc(*str++, stdout);
  33. } else if( *(format+) == 'o')
  34. {
  35. char store[];
  36. int i = va_arg(arg, int);
  37. char* str = store;
  38. itoa(i, store, );
  39. while( *str != '\0') putc(*str++, stdout);
  40. } else if( *(format+) == 'x')
  41. {
  42. char store[];
  43. int i = va_arg(arg, int);
  44. char* str = store;
  45. itoa(i, store, );
  46. while( *str != '\0') putc(*str++, stdout);
  47. } else if( *(format+) == 's' )
  48. {
  49. char* str = va_arg(arg, char*);
  50. while( *str != '\0') putc(*str++, stdout);
  51. }
  52.  
  53. // Skip this two characters.
  54.  
  55. format += ;
  56. } else {
  57. putc(*format++, stdout);
  58. }
  59. }
  60.  
  61. va_end (arg);
  62.  
  63. return done;
  64. }
  1. C常用库函数实现
  2. // ---------- strlen -------------
  3. int strlen(char *t){
  4. int length = ;
  5. if(t == NULL)
  6. return -;
  7.  
  8. while (*t != '\0') {
  9. t++;
  10. length++;
  11. }
  12. return length;
  13. }
  14.  
  15. size_t strlen(const char *s)
  16. {
  17. const char *sc;
  18.  
  19. for (sc = s; *sc != '\0'; ++sc);
  20.  
  21. return sc - s;
  22. }
  23.  
  24. // ---------- trim -------------
  25.  
  26. void ltrim ( char *s )
  27. {
  28. char *p;
  29. p = s;
  30. while ( *p == ' ' || *p == '\t' ) {p++;}
  31. strcpy ( s,p );
  32. }
  33.  
  34. void rtrim ( char *s )
  35. {
  36. int i;
  37.  
  38. i = strlen ( s )-;
  39. while ( ( s[i] == ' ' || s[i] == '\t' ) && i >= ) {i--;};
  40. s[i+] = '\0';
  41. }
  42.  
  43. void trim ( char *s )
  44. {
  45. ltrim ( s );
  46. rtrim ( s );
  47. }
  48.  
  49. // ---------- strcpy -------------
  50.  
  51. char *strcpy(char *dest, const char *src)
  52. {
  53. char *tmp = dest;
  54.  
  55. while ((*dest++ = *src++) != '\0');
  56.  
  57. return tmp;
  58. }
  59.  
  60. // ---------- strcat -------------
  61.  
  62. char *strcat(char *dest, const char *src)
  63. {
  64. char *tmp = dest;
  65.  
  66. while (*dest)
  67. dest++;
  68. while ((*dest++ = *src++) != '\0');
  69.  
  70. return tmp;
  71. }
  72.  
  73. // ---------- strstr -------------
  74.  
  75. char *strstr(const char *s1, const char *s2)
  76. {
  77. int l1, l2;
  78.  
  79. l2 = strlen(s2);
  80. if (!l2)
  81. return (char *)s1;
  82. l1 = strlen(s1);
  83. while (l1 >= l2) {
  84. l1--;
  85. if (!memcmp(s1, s2, l2))
  86. return (char *)s1;
  87. s1++;
  88. }
  89.  
  90. return NULL;
  91. }
  92.  
  93. // ---------- memcmp -------------
  94.  
  95. int memcmp(char *cs, char *ct, size_t count)
  96. {
  97. char *su1, *su2;
  98. int res = ;
  99.  
  100. for (su1 = cs, su2 = ct; < count; ++su1, ++su2, count--)
  101. if ((res = *su1 - *su2) != )
  102. break;
  103. return res;
  104. }
  105.  
  106. // ---------- strcmp -------------
  107.  
  108. int strcmp(const char *cs, const char *ct)
  109. {
  110. unsigned char c1, c2;
  111.  
  112. while () {
  113. c1 = *cs++;
  114. c2 = *ct++;
  115. if (c1 != c2)
  116. return c1 < c2 ? - : ;
  117. if (!c1)
  118. break;
  119. }
  120.  
  121. return ;
  122. }

编程实现C库函数的更多相关文章

  1. 《Linux及安全》实践2

    <Linux及安全>实践2 [edited by 5216lwr] 一.Linux基本内核模块 1.1理解什么是内核模块 linux模块是一些可以作为独立程序来编译的函数和数据类型的集合. ...

  2. Linux内核装载和启动一个可执行程序

    “平安的祝福 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 理解编 ...

  3. 第五章 HID设备

    5.1 HID介绍 为简化USB设备的开发过程,USB提出了设备类的概念.所有设备类都必须支持标准USB描述符和标准USB设备请求.如果有必要,设备类还可以自行定义其专用的描述符和设备请求,这分别被称 ...

  4. 实验七:Linux内核如何装载和启动一个可执行程序

    原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 题目自拟,内容围绕对Linu ...

  5. Linux内核如何启动并装载一个可执行程序

    2016-04-07 张超<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000#/info 一.理解编译链接的 ...

  6. 《Linux内核分析》课程第七周学习总结

    姓名:何伟钦 学号:20135223 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  7. LINUX内核分析第七周学习总结——可执行程序的装载

    LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...

  8. Linux内核实验作业七

    实验作业:Linux内核如何装载和启动一个可执行程序 20135313吴子怡.北京电子科技学院 [第一部分]理解编译链接的过程和ELF可执行文件格式 1.编译链接的过程 2.ELF可执行文件格式 一个 ...

  9. Linux内核分析-Linux内核如何装载和启动一个可执行程序

    ID:fuchen1994 实验要求: 理解编译链接的过程和ELF可执行文件格式,详细内容参考本周第一节: 编程使用exec*库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链接和运行时动态 ...

随机推荐

  1. Krapo 2

    The krpano Viewer is a small and very flexible high-performance viewer for all kind of panoramic ima ...

  2. 『PyTorch』第五弹_深入理解autograd_中:Variable梯度探究

    查看非叶节点梯度的两种方法 在反向传播过程中非叶子节点的导数计算完之后即被清空.若想查看这些变量的梯度,有两种方法: 使用autograd.grad函数 使用hook autograd.grad和ho ...

  3. HDOJ1008

    #include "iostream" using namespace std; int main() { ) { int n; cin >> n; ) break; ...

  4. PHP:第三章——PHP中返回引用的函数

    <?php header("Content-Type:text/html;charset=utf-8"); $i=1; function &F(){ global $ ...

  5. learning shell built-in variables (1)

    Shell built-in variables [Purpose]        Learning shell built-in variables, example $0,$1,$2,$3,$#, ...

  6. IScroll的诞生和缺点

    转自http://lhdst-163-com.iteye.com/blog/1239784 iscroll.js是Matteo Spinelli开发的一个js文件,使用原生js编写,不依赖与任何js框 ...

  7. 关于apicloud ios自定义模块引用第三方framework not found for architecture armv7

    1 .自定义模块 新建模块必须是静态库 2.使用的第三方framework 必须要把 .h文件开放出来 3.编译要用 真机模式 (上传模块以后,自定义load要编译,用生成的二维码调试) 4. 添加监 ...

  8. 1.1 C++布尔类型(bool)

    注意: c++ 中 cout << true << endl;  输出为 1: 布尔类型(bool)是C++新增的一种基本数据类型.在标准的C语言中并未定义bool类型,如果需 ...

  9. 玩转X-CTR100 l STM32F4 l OLED显示-SSD1306无字库

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ]      OLED显示屏具有自发光特性,不需要背光, ...

  10. 2019.1.10 L223

    Heavy rains that brought additional pollution downstream last year contributed to the first decline ...