浅析C基础知识_第1页
浅析C基础知识_第2页
浅析C基础知识_第3页
浅析C基础知识_第4页
浅析C基础知识_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、浅析C 基础知识浅析C 基础知识1一、C/C+基础知识31. C/C+内存管理32.小端存储和大端存储43.C+的指针使用44.运算符优先级45.二维数组的动态申请56.extern "C"声明的作用57.指针和引用的区别,指针和数组的区别,const与define的区别58.如何判定程序是由C/C+编译器编译出来的?59.const的作用,static的作用510.变量字节对齐:为了加快内存寻址的效率,在C+内存管理时一般选取的是4字节对齐511.const与指针612.操作符重载613.函数调用传值与传引用714.volatile与C/C+的四种cast函数7

2、15.C+ 类的实例化如果没有参数是不需要括号的,否者就是调用函数并且返回对应的对象716.const修饰函数时,标志该函数不会修改this指针的内容817.const可以重载,这是基于编译器编译时对函数进行重命名实现的818.override(覆盖), overload(重载), polymorphism(多态)819.const char* a, char const*, char*const的区别820.typename和class的区别8二、面向对象和C+特性描述91.面向对象三个基本特征92.多态93.什么是纯虚函数和纯虚类94.什么是虚函数95.运行时绑定和虚函数表96.空类的大小

3、不是零97.深拷贝与浅拷贝108.只要在基类中使用了virtual关键字,那么派生类中无论是否添加virtual,都可以实现多态109.虚拟析构函数1010.public,protected, private权限1011.可重入函数(多线程安全),即该函数可以被中断,就意味着它除了自己栈上的变量以外不依赖任何环境1012.操作系统内存管理有堆式管理、页式管理、段式管理和段页式管理1013.C+四种CAST操作符1014.shared_ptr是一个包含引用计数的智能指针12三、基础的数据结构编程知识131.数组13排序13具体的每种排序算法的实现14字符串处理程序16链表处理 

4、0;19二叉树处理19其他21四、STL基础知识211.STL212.STL容器简介213. list使用224. stack使用225. vector使用226. Map/HashMap使用22五、多线程和网络编程231.原子锁 自旋锁 信号量 互斥锁232.C+多线程和多进程233.TCP三次握手过程244.socket编程基础245. 短连接和长连接246. 多线程编程基础247. TCP与UDP的区别258. OSI7层模型259. C+实现单例模式2510. C+异常处理2611. 多线程编程2612. SQL注入26六、C+ 语言新特性26七、其他计算机基础知识26参考文献:261

5、.进程内存空间262.原子操作、信号量、自旋锁、互斥锁263.二叉树面试题目274. 多线程同步方法275.OSI 7层模型276. C+四种CAST277. 数据库存储过程介绍278.C+ 11的新特性- auto的使用279. Boost总结汇总27来源:极客头条    最近想对C+的面试题目进行一下更加具体的整理。其实认真思考一下C+程序员的面试,我们可以发现对程序员的能力的考察总是万变不离其中,这些基础知识主要分为五部分:一、C/C+基础知识二、C/C+的一些特性,如面向对象,内存管理 三、基础的数据结构编程的知识。 四、stl的一些基础知识。五、网络编程

6、、多线程的知识、异常处理基础知识    本文试图覆盖C/C+面试的每一个知识点,所以对每个知识点介绍的并不深入。本文适合已经对一下具体知识有所了解的人,我对每个点都有粗略的讲解,如果想深入理解请阅读相关具体知识。一、 C/C+的基础知识:包括指针、字符串处理、内存管理。二、面向对象基础知识:包括多态、继承、封装。 多态的实现方式?多态的好处?三、基础的数据结构面试:数组、链表、字符串操作、二叉树。这里要说的话就说的很多了,具体的有使用一些数据结构包括stl list, vector, map, hashmap, set。四、stl的一些基础知识。五、网络编程、多线程和异常处

7、理的基础知识。六、C+ 语言新特性。七、其他计算机基础。一、C/C+基础知识1. C/C+内存管理C/C+的内存分为:堆、栈、自由数据区、静态数据区和常量数据区。栈: 函数执行时,函数内部的局部变量在栈上创建,函数执行结束栈的存储空间被自动释放。堆:就是那些new分配的内存块,需要程序员调用delete释放掉。自由数据区:就是那些调用malloc的内存块,需要程序员调用free释放掉。全局存储区:全局变量和静态变量被存放到同一块存储区域。静态存储区:这里存放常量,不允许修改。堆和栈的区别:a.管理方式不同:堆需要程序员手动维护。 b.栈的存储空间远小于堆。堆几乎不受限制。 c.生长方

8、式不同。栈是从高地址空间向低地址空间生长,堆是从低地址空间向高地址空间生长。 d.效率不同:栈要远快于堆。new和delete的区别:new和delete是C+的函数会调用,构造函数和析构函数。而malloc和delete只是分配对应的存储空间。注意问题: 1. 意外处理:内存申请失败处理。2.内存泄漏:申请的地址空间一定要释放。 3.野指针:避免指针未赋值使用,一定要初始化。给出一个图吧,关于内存空间的分配的: 左边的是UNIX/LINUX系统的执行文件,右边是对应进程逻辑地址空间的划分情况。     2.小端存储和大端存储小段:高位存在高地址上;大端

9、:低位存在高地址上。判定代码:unsigned short test = 0x1234;if( *(unsigned char *)&test=0x12 )/return Big_Edian;/高位在低地址空间 大端存储3.C+的指针使用a. 指针数组 与 数组指针: 注意的结合优先级比*要高。那么int *p3;我们就得到了一个数组,数组的每个元素是int *的。而int (*p)3;/我们就得到了一个指针,指向的是一个长度为3的一维数组。b. 函数指针:例如对函数:int funcA(int a,int b); 

10、 我们可以定义一个指针指向这个函数:int (*func)(int,int);  func=funcA;c. ptr+; 指针ptr的值加上了sizeof(ptr); 4.运算符优先级a. 比较常考的就是 +和-与*、&、.的优先级对比;注意正确的优先级是:.  >  +  >  -  >  *  >  &5.二维数组的动态申请int *a=new int *10;for(i=0;i<10;i+)ai=new int10;6.ex

11、tern "C"声明的作用C+中引用C语言的函数和变量需要使用extern "C"来进行修饰。因为C+为了支持多态,函数和变量命名的方式和C不同,因此如果一个模块的函数和变量需要被其他模块使用,就需要使用extern "C"来修饰。该修饰制定编译器变量和函数是按照C语言方式进行链接的。7.指针和引用的区别,指针和数组的区别,const与define的区别指针和引用的区别:引用可以看作是变量的别名,不可以指向其他的地址,不能为空。指针和数组的区别:指针可以指向其他地址,使用sizeof计算时两者的结果不同。onst与指针的区别:cons

12、t定义的变量有类型,而define只是编译器的简单替换。8.如何判定程序是由C/C+编译器编译出来的?#ifdef _cplusplus#else#endif9.const的作用,static的作用 a. const 指定变量不可修改。b. static 指定变量存在静态数据区,并且只初始化一次。10.变量字节对齐:为了加快内存寻址的效率,在C+内存管理时一般选取的是4字节对齐如下变量占用8个字节:struct Nodeint a,char b;11.const与指针char * const p; /指针不可改char const *p; /指针指向的对象不可修改12.操作符重载C/

13、C+ 里大多数运算符都可以在 C+ 中被重载。C 的运算符中只有 . 和 ?:(以及sizeof,技术上可以看作一个运算符)不可以被重载。C+ 增加了一些自己的运算符,除了 : 和 .* 外,大多数都可以被重载。a. 单目操作符:Point &Point: operator+();/+a;Point &Point: operator+(int);/a+b. 双目操作符:Point &Point: operator+=(Point b)/ +=源代码如下:1. class Point 

14、0;2. public:  3.     int x;  4.     int y;  5. public:  6.     void Print()  7.         cout<<"x="<<this->x<

15、;<endl;  8.         cout<<"y="<<this->y<<endl;  9.       10.     Point()  11.         x=0;  12.

16、        y=0;  13.       14.     Point(const Point &a)  15.         x=a.x;  16.         

17、;y=a.y;  17.       18.     Point(int x,int y)  19.         this->x=x;  20.         this->y=y;  21.   

18、60;   22.     Point& operator+=(Point b);  23.     Point& operator+();  24.     Point& operator+(int);  25. ;  26. Point& Point:operator+=(Point

19、 b)  27.     x += b.x;  28.     y += b.y;  29.     return *this;  30.   31.   32. Point& Point:operator+()  33.    &

20、#160;this->x+;  34.     this->y+;  35.     return *this;  36.   37. Point& Point:operator+(int)  38.     Point a(*this);  39.     this-

21、>x+;  40.     this->y+;  41.     return a;  42.   43. int main()  44.     Point *a=new Point(1,2);  45.     Point *b=new Poi

22、nt(3,4);  46.     Point c(10,20);  47.     *a+=c;  48.     a->Print();  49.     +c;  50.     c.Print();  51.     

23、;c+;  52.     c.Print();  53.     return 0;  54.   13.函数调用传值与传引用传值不会修改传入参数的值,而传引用会修改传入参数的值。14.volatile与C/C+的四种cast函数volatile修饰的变量,编译器不会做优化,每次都是到内存中去读取或者写入修改。C+有四种cast函数:static_cast,dynamic_cast,const_cast,volatile_c

24、ast。15.C+ 类的实例化如果没有参数是不需要括号的,否者就是调用函数并且返回对应的对象例如如下代码就会报错:1. struct Test  2.   3.     Test(int )    4.     Test()    5.     void fun()    6. ;

25、0; 7.   8. int main(void)  9.   10.     Test a(1);  11.     a.fun();  12.     Test b;  13.     b.fun();  14.    

26、60;return 0;  15.   16.const修饰函数时,标志该函数不会修改this指针的内容C+ 里面的const修饰函数时,标志该函数不会修改this指针的内容,而且const不能修饰非类内部的函数。17.const可以重载,这是基于编译器编译时对函数进行重命名实现的例如f( int a), f(const int a)是两个不同的函数了。18.override(覆盖), overload(重载), polymorphism(多态)19.const char* a, char const*, char*const的区别const

27、char * pa;/一个指向const类型的指针char * const pc;/const修饰的指针20.typename和class的区别在模版中使用时,class与typename可以替换。在嵌套依赖类型中,可以声明typename后面的字符串为类型名,而不是变量。例如:1. class MyArray /暂时还不是很懂,就先睡觉了。  2.    3. public:  4. typedef int LengthType;  5. .  

28、;6.   7.   8. template<class T>  9. void MyMethod( T myarr )   10.    11. typedef typename T:LengthType LengthType;   12. LengthType length = myarr.GetLength; 

29、  13.  二、面向对象和C+特性描述1.面向对象三个基本特征继承、多态和封装。2.多态多态是面向对象继承和封装的第三个重要特征,它在运行时通过派生类和虚函数来实现,基类和派生类使用同样的函数名,完成不同的操作和实现相隔离的另一类接口。多态提高了代码的隐藏细节实现了代码复用。3.什么是纯虚函数和纯虚类有些情况下基类不能对虚函数有效的实现,我们可以把它声明为纯虚函数。此时基类也无法生成对象。4.什么是虚函数虚函数是类内部使用virtual修饰的,访问权限是public的,并且非静态成员函数。虚函数是为了实现动态连接,定义了虚函数以后对基类和派生类的虚函数以同样形式

30、定义,当程序发现virtual虚函数以后会自动的将其作为动态链接来处理。纯虚函数在继承类实现时,需要全部实现。如public virtual function f()=0;注:下列函数不能被声明为虚函数:普通函数(非成员函数);静态成员函数;内联成员函数;构造函数;友元函数。5.运行时绑定和虚函数表动态绑定:绑定的对象是动态类型,其特性依赖于对象的动态特性。虚函数表: C+的多态是通过动态绑定和虚函数表来实现的。这是虚函数的地址表,存储着函数在内存的地址。一般类的对象实例地址就是虚函数表。有虚函数覆盖时,虚函数的地址存储的是被覆盖的子类的函数的地址。其实知道虚函数表了,我们就可以通过操作指针的

31、方式访问一些额外的数据(当然如果直接写成代码会编译不通过的)。对于基类指针指向派生类时:我们可以通过内存访问派生类未覆盖基类的函数,访问基类的非public函数。6.空类的大小不是零因为为了确保两个实例在内存中的地址空间不同。如下,A的大小为1,B因为有虚函数表的大小为4.class A;class B:public virtual A; 多重继承的大小也是1,如下:                              class

32、 Father1; class Father2;class Child:Father1, Father2;7.深拷贝与浅拷贝C+会有一个默认的拷贝构造函数,将某类的变量全部赋值到新的类中。可是这种情况有两个例外:(1) . 类的默认构造函数做了一些额外的事情,比如使用静态数据统计类被初始化的次数(此时浅拷贝也无法解决问题,需要额外的修改拷贝构造函数)。 (2). 类内部有动态成员:此时发生拷贝时就需要对类内部的动态成员重新申请内存空间,然后将动态变量的值拷贝过来。8.只要在基类中使用了virtual关键字,那么派生类中无论是否添加virtual,都可以实现多态9.虚拟析构函数在使用基类指针指向

33、派生类时,如果没有定义虚拟析构函数那么派生类的析构函数不会被调用,动态数据也不会被释放。构造函数和析构函数的调用顺序为:先基类构造函数,再派生类构造函数。析构时,先派生类析构函数,再基类析构函数。10.public,protected, private权限privated:类成员函数、友元函数。 protected:派生类、类成员函数、友元函数。public:所有11.可重入函数(多线程安全),即该函数可以被中断,就意味着它除了自己栈上的变量以外不依赖任何环境12.操作系统内存管理有堆式管理、页式管理、段式管理和段页式管理堆式管理:把内存分为一大块一大块的,所需程序片段不在主村时就分配一块主存

34、程序,把程序片段load入主存。页式管理:把主页分为一页一页的,每一页的空间都比块小很多。段式管理:把主存分为一段一段的,每一段的空间比一页一页的空间小很多。段页式管理。 13.C+四种CAST操作符C/C+的强制转换风格如下: (T) expression或 T(expression) 函数风格。C+定义了四种转换符: reinterpret_cast、tatic_cast、dynamic_cast和const_cast,目的在于控制类之间的类型转换。reinterpreter_cast <type-id> (expression) 能够实现非相关类型之间的转换,但只是

35、复制原的数据到目的地址,可能包含无用值,且不可移植。如:double d=reinterpret_cast<double &>(n);                   const_cast<type-id> expression: 修改const或volatile属性、消除对象的常量属性。   static_cast<type-id> ex

36、pression: 父子类之间转换、空指针->目标指针、任何类型转化为void类型、任意类型转换。dynamic_cast<type-id> expression: 是唯一不能用旧风格执行的强制转换。用于多态类型的任意隐式类型转换及相反的过程。基类指针转化为派生类时,基类需要有虚函数(否则编译报错)。相对于static_cast,增加了安全检验。1. /结论:父指针指向子对象地址,不用强转,即可。  2. /基类没有虚函数时,只有static_cast可以编译通过。基类有虚函数时dynamic_cast也可以编译通过。  3. clas

37、s Base  4.   5. public:  6. Base()a1=1;  7. virtual void test()  8. int a1;  9. ;  10. class Derive:public Base  11.   12. public:  13. Derive()a2=2;  14. int&#

38、160;a2;  15. ;  16. int main(int argc, char *argv)  17.   18. Base *pb;  19. Derive *pd;  20. Base b;  21. Derive d;  22. cout <<"&b:"<<&b<<

39、;endl;  23. cout<<"&d:"<<&d<<endl;  24.   25. pb=&d;  26. cout<<_LINE_<<"pb:"<<pb<<endl;  27. pb=static_cast<Base*>(&d);  28. cout<<_LINE_<<&quo

40、t;pb:"<<pb<<endl;  29. pb=dynamic_cast<Base*>(&d);  30. cout<<_LINE_<<"pb:"<<pb<<endl;  31.   32. /pd=&b;/error  33. /cout<<_LINE_<<"pd:"<<pd<<endl;

41、60; 34. pd=static_cast<Derive*>(&b);  35. cout<<_LINE_<<"pd:"<<pd<<endl;  36. pd=dynamic_cast<Derive*>(&b);/error  37. cout<<_LINE_<<"pd:"<<pd<<endl;  38.   

42、39. return 0;  40.   14.shared_ptr是一个包含引用计数的智能指针它的引用计数是安全且无锁的,但内存对象的读写不是,因为shared_ptr有两个数据成员,读写操作不能原子化。shared_ptr的线程安全级别和内建类型、标准库容器、string一样。shared_ptr实体可以被两个线程同时写入。如果要从多个线程同时读写一个shared_ptr对象,那么需要加锁。使用示例如下:1. #include "boost/shared_ptr.hpp"  2. #incl

43、ude <cassert>  3. #include <stdlib.h>  4. #include <iostream>  5. #include "boost/make_shared.hpp"  6. using namespace std;  7. class shared        

44、;                            /一个拥有shared_ptr的类    8.   9. private:  10.         

45、boost:shared_ptr<int> p;                          /shared_ptr成员变量    11. public:  12.        &

46、#160;shared(boost:shared_ptr<int> p_):p(p_)          /构造函数初始化shared_ptr        13.         void print()        

47、60;                       /输出shared_ptr的引用计数和指向的值        14.           15.    &#

48、160;            cout << "count:" << p.use_count() << " v=" <<*p << endl;  16.         

49、0; 17. ;  18. void print_func(boost:shared_ptr<int> p)                               /使用shared_ptr作为函数参数 

50、0;  19.   20.         /同样输出shared_ptr的引用计数和指向的值        21.         cout << "count:" << p.use_count() <<

51、0;" v=" <<*p << endl;  22.   23. void f()  24.   25.         typedef vector<boost:shared_ptr<int> > vs;    /一个持有shared_ptr的标准容

52、器类型        26.         vs v(10);                              

53、60;/声明一个拥有10个元素的容器,元素被初始化为空指针         27.         int i = 0;  28.         for (vs:iterator pos = v.begin(); pos != 

54、v.end(); +pos)  29.           30.                 (*pos) = boost:make_shared<int>(+i);     /使用工厂函数赋值  &#

55、160;         31.                 cout << *(*pos) << ", "            

56、/输出值        32.           33.         cout << endl;  34.         boost:shared_ptr<int> p 

57、;= v9;  35.         *p = 100;  36.         cout << *v9 << endl;  37.   38. int main()  39.   40.   

58、;      boost:shared_ptr<int> p(new int(100);  41.         shared s1(p);  42.         s1.print();  43.       &

59、#160; shared s2(p);                        /构造两个自定义类         44.         s1.print();&

60、#160; 45.         s2.print();  46.         *p = 20;                        

61、            /修改shared_ptr所指的值        47.         print_func(p);  48.         s1.print();  49.  

62、 50.         f();  51.   52.   53. /对应于shared_ptr的是<span style="font-family: Arial, Helvetica, sans-serif;">static_pointer_cast 和 dynamic_pointer_cast,它的用法和static_cast、dynamic_cas

63、t很像。</span>  三、基础的数据结构编程知识其实我理解作为面试来说,一般会面时应聘者的基础知识,如果对于过于复杂的图程序,动态规划一般不太适合。而对于数组、链表、二叉树、字符串处理的考察,既能考察出应聘者的基础知识、代码风格、命名书写规范,又能考察出应聘者的代码是否包含bug。而比较深入的一些题目一般只作为脑筋急转弯或者给出思路,博主在此提醒各位,面试时准确性更加重要,如果一时想不出来,可以首先给出一个效率较低的实现,然后再一步步优化(注意边界条件,小心谨慎测试)。下面分析一下对于数组、链表、二叉树和字符串处理的常考题目:1. 数组:一般到了数组就会考察

64、排序(稳定性、平均、最好、最差时间复杂度/内存使用、不同情况下那种最快)、二分的特性。2. 链表:链表的插入,逆序,判断链表相交,找到链表交点,链表的删除。3. 二叉树:二叉树的深度、前序/中序/后序遍历、二叉树的叶子数目、二叉树的节点数目、二叉树的层次遍历。4. 字符串的处理:atoi,itoa,字符串替换、字符串的查找。再次特意提醒一下,字符串处理设计指针的处理所以指针的内存访问控制,需要使用更多的注意,比如参数为空,内存申请失败,返回值控制,指针加减。   1.数组排序各种排序算法的对比如下图所示 。排序法平均时间最差情形稳定度额外空间备注冒泡O(n2)O(

65、n2)稳定O(1)n小时较好交换O(n2)O(n2)不稳定O(1)n小时较好选择O(n2)O(n2)不稳定O(1)n小时较好插入O(n2)O(n2)稳定O(1)大部分已排序时较好基数O(logRB)O(logRB)稳定O(n)B是真数(0-9),R是基数(个十百)ShellO(nlogn)O(ns) 1<s<2不稳定O(1)s是所选分组快速O(nlogn)O(n2)不稳定O(nlogn)n大时较好归并O(nlogn)O(nlogn)稳定O(1)n大时较好堆O(nlogn)O(nlogn)不稳定O(1)n大时较好具体的每种排序算法的实现a) 快速排序实现:1. int pa

66、rtition(int a,int low,int high)  2.     int data=alow,tem;  3.     int i=low+1,j=low+1;  4.   5.     while(j<=high)  6.        

67、 if(aj>data)  7.             j+;  8.         else  9.             tem=ai;  10.   &

68、#160;         ai=aj;  11.             aj=tem;  12.             i+;  13.      

69、60;      j+;  14.           15.       16.     alow=ai-1;  17.     ai-1=data;  18.     return i-

70、1;  19.   20.   21.   22.   23. void qsort1(int a,int low,int high)  24.     if(low>=high)  25.         return;  26.    &#

71、160;int mid=partition(a,low,high);  27.     if(mid-1>low)  28.         qsort1(a,low,mid-1);  29.     if(high>mid+1)  30.         

72、qsort1(a,mid+1,high);  31.   32.   b) 堆排序实现:1. void HeapModify(int a, int i, int length)  2.     int j=-1;  3.     if( i*2+1 < length )  4. &#

73、160;       if( ai*2+1>ai)  5.             j=i*2+1;  6.           7.       8.    &#

74、160;if( i*2 +2 < length)  9.         if( ai*2 +2 > ai && a2*i+2 > a2*i+1)  10.               

75、  j=i*2+2;  11.           12.       13.   14.     if( j> 0)  15.         int tem;  16.  

76、;       tem=ai;  17.         ai=aj;  18.         aj=tem;  19.         HeapModify(a,j,length);  20.  

77、     21.   22. void Heap_sort(int a,int length)  23.     int i,tem;  24.     for(i=length/2;i>=0;i-)  25.         HeapModify(a,i,len

78、gth);  26.       27.   28.     for(i=0;i<length-1;i+)  29.         tem=a0;  30.         a0=alength-1-i;  31.  &#

79、160;      alength-1-i=tem;  32.         HeapModify(a,0,length-i-1);  33.       34.   c ) 最大子数组求和:1. int atoi1(char *str)  2.    &#

80、160;assert(str!=NULL);  3.     int result=0,pos=1;  4.     if(*str='-')  5.         pos=-1;  6.         str+;  7. 

81、60;     8.     while(*str!='0')  9.         assert(*str<='9'&&*str>='0');  10.         result=result*10+*str-'0&#

82、39;  11.         str+;  12.       13.     return result*pos;  14.   15.   字符串处理程序a). atoi实现:1. int atoi1(char *str)  2.   

83、60; assert(str!=NULL);  3.     int result=0,pos=1;  4.     if(*str='-')  5.         pos=-1;  6.         str+;  7

84、.       8.     while(*str!='0')  9.         assert(*str<='9'&&*str>='0');  10.         result=result*10+*str-

85、9;0'  11.         str+;  12.       13.     return result*pos;  14.   15.   b). itoa实现:1. char *itoa1(int num,int k)  2.  

86、   char data="0123456789ABCDEF"  3.     bool pos=true;  4.     int count=1,tem;  5.     int num1=num;  6.     if(num<0)  7

87、.         num=-num;  8.         pos=false;  9.         count+;  10.       11.     while(num>0)

88、60; 12.         num=num/k;  13.         count=count+1;  14.       15.     char *result=new charcount;  16.    

89、 char *presult=result,*pstr;  17.     if(pos=false)  18.         *presult+='-'  19.       20.     pstr=presult;  21.   22.

90、     while(num1>0)  23.         *presult+=datanum1%k;  24.         num1=num1/k;  25.       26.     *presult-='0&#

91、39;  27.     while(pstr<presult)  28.         tem=*pstr;  29.         *pstr=*presult;  30.         *presult=tem; 

92、; 31.         *presult-;  32.         *pstr+;  33.       34.   35.     return result;  36.  c). 将字符串空格替换为目的串的实现:1.

93、char * Replace_Str(char * str, char * target)  2.     assert(str!=NULL&&target!=NULL);  3.     char *pstr=str;  4.     int count=0;  5.   

94、;  while(*pstr!='0')  6.         if(*pstr=' ')  7.             count+;  8.           9. &

95、#160;  pstr+;  10.   11. char * result=new charsizeof(str)+count*strlen(target);  12. char *presult=result;  13. for(pstr=str;pstr!='0'pstr+)  14.     if(*pstr!=' ')  15

96、.         *presult=*pstr;  16.       17.     else  18.         char *ptarget=target;  19.        

97、60;while(*ptarget!='0')  20.             *presult+=*ptarget+;  21.           22.       23.   24. *presult='0' 

98、; 25. return result;  d). strcpy实现:1. void strcpy1(char * source, char * dest)  2.     assert(source!=NULL&&dest!=NULL);  3.     char * psource=source, *pdest=dest;

99、60; 4.     while(*psource!='0')  5.         *pdest+=*psource+;  6.       7.     *pdest='0'  8.   e). 查找目的串第一次出现位置(最快的肯定是KMPO(M+N)

100、),或者查找目的串在源串中的出现次数:1. <span style="font-size:14px;">int Find_Str(const char* source,const char* target) /查找目的串在源串中出现的位置,最弱的方法  2.     assert(source!=NULL&&target!=NULL);  3.   4.   

101、  int i,j,i1;  5.     int len_source=strlen(source),len_target=strlen(target);  6.   7.     for(i=0;i<len_source;i+)  8.         i1=i;  9.  &#

102、160;      for(j=0;sourcei1=targetj&&j<len_target;i1+,j+);  10.         if(j=len_target)  11.             return i;  12. 

103、0;     13.     return -1;  14. </span>  f). memcopy实现:1. void *memcpy1(void * dest, const void * source, size_t num)/注意需要考虑内存重叠的部分,特别的dest在source数据区间内部时候的处理  2.  &#

104、160;  assert(dest!=NULL&&source!=NULL);  3.     int i;  4.     byte *psource=(byte *) source;  5.     byte *pdest=(byte *) dest;  6.   7.     if(pdest>psource&&pdest<psource+num)  8.         for(i=num-1;i&g

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论