C++学习笔记

---恢复内容开始---

随堂笔记

1.float 为单精度浮点型,使用 ” %f “输出;

初始化时:float a=0.23f;  

这里要加一个f表示是单精度浮点型;

 

2.double为双精度浮点型,使用“ %lf ”输出;

初始化时:double a=0.23;

这里不f表示为双精度浮点型;

 

3.printf();

使用printf打印数据时,“%08x”表示以十六进制输出,并补齐8位;

           “%.02f”表示保留两位小数;

4.对于取余运算,%,左右操作数不能为小数;

5.在表达式中,各种类型混合运算,编译器会自动类型提升::

  char 与 short 一起运算,char会被提升为short;

  int 与double一起运算,int会被提升为double;

6.使用unsigned类型进行位运算;

7.

 1 #include <iostream>
 2 using namespace std;
 3 
 4 void swap(int* a, int* b)
 5 {
 6     int t = *a;
 7     *a = *b;
 8     *b = t;
 9 }
10 int main()
11 {
12     int a=10;
13     int b=20;
14     swap(&a, &b);
15     printf("a=%d,b=%d", a, b);
16     system("pause");
17     return 0;
18 }

 

8.引用的使用方法:

1 int a=10;
2 int& r=a;
3 这里的r就是一个引用的使用方法。

  这里 r 其实就是一个 a 的别名,也就是说r 的地址和a 的地址是相同的;

注意:1.引用在定义的时候,必须要初始化,也就是在创建的时候就要与目标对象绑定;

      2.引用在定义的时候就与目标对象绑定了,无法解绑!!!

 9.

 1 void test(int& a)    //这里相当于一个初始化过程:int&a = r;
 2 {    
 3     a = 99;
 4 }
 5 
 6 int main()    
 7 {
 8     int r = 10;
 9     test(r);
10 
11     system("pause");
12     return 0;
13 }

 10.

 1 int num=0;
 2 int& test()    //这里相当于一个初始化过程:int&a = r;
 3 {    
 4     int&a = num;
 5     return a;
 6 }
 7 
 8 int main()    
 9 {
10     int& b=test();
11     b = 10;
12 
13     system("pause");
14     return 0;
15 }

演化:

 1 int num=0;
 2 int& test()        //这里返回的是num的引用;
 3 {    
 4     return num;
 5 }
 6 
 7 int main()    
 8 {
 9     int& b=test();
10     b = 10;
11 
12     system("pause");
13     return 0;
14 }

返回值引用类型时,可以作为左值使用; 

 11.字符串的深度学习;

 1 int main()    
 2 {
 3     char buf[] = "nihao";
 4 
 5     char* p = "nihao";
 6 
 7     int a = sizeof(p);    //a=4;
 8     int b = strlen(p);    //b=5
 9 
10     int c = sizeof(buf);   //c=6;
11     int d = strlen(buf);   //d=5;
12 
13     system("pause");
14     return 0;
15 }

12.字符串的添加删除

  

 1 void ease(char *p, char del)
 2 {
 3     int count = 0;
 4     int len = strlen(p);
 5     char *copy = (char*)malloc(len+1);
 6 
 7     for (int i = 0; i < len; i++)
 8     {
 9         if (p[i] != del)
10         {
11             copy[count] = p[i];
12             count++;
13         }
14     }
15     copy[count] = 0;
16     strcpy(p, copy);
17     free(copy);
18 }
19 
20 
21 int main()    
22 {
23     char buf[] = "nihao wo ai zao an";
24     int a = sizeof(buf);
25     ease(buf, 'o');
26     
27     system("pause");
28     return 0;
29 }

13.sprintf函数的使用;

 sprintf函数是将其他数据类型转换成字符串类型;
 

1 char buf[100];
2 sprintf(buf, "name:%s ,phone:%d", "nihao", 123);

  sprintf函数的格式:int sprintf( char *buffer, const char *format [, argument,...] );

            bufferchar型指针,指向将要写入的字符串的缓冲区。

            format:格式化字符串。
            [argument]...:可选参数,可以是任何类型的数据。

   sprintf 返回以format为格式argument为内容组成的结果被写入buffer 的字节数,结束字符‘\0’不计入内。即,如果“Hello”被写入空间足够大的buffer后,函数sprintf 返回5。

14.sscanf函数的使用方法;

  int sscanfconst char *buffer, const char *format, [ argument ] ...   ); 

  将buffer中的字符串按照相应的格式读取到相对应的变量中;

  其返回值为,从buffer中读取中的字段数;

  需要注意的是:format的格式要和buffer中的格式模式相同;

  

 1 int main()    
 2 {
 3     char buf[100];
 4     int ret=sprintf(buf, "name:%s ,phone:%s", "nihao","weiyouqing");
 5     printf("%s",buf);
 6 
 7 
 8     char m[111] = {0};
 9     char n[111] = {0};
10     char b[] = "nihao weiyouqing 123";
11     int size = sizeof(b);
12     int len = strlen(b); 
13     int a;
14     int re=sscanf(b,"%s %s %d",m,n,&a);
15 
16 
17     system("pause");
18     return 0;
19 }

    

15.rand()函数使用方法;

 随机数产生函数;通常和srand()函数一起使用;

 1 int main()    
 2 {
 3     
 4     srand(time(NULL));
 5     for (int i=0;i<10;i++)
 6     {
 7         int a = rand() % 100;
 8         printf("%.2lf\n",a/100.0);
 9     }
10     system("pause");
11     return 0;
12 }

16..time.h函数的使用;

  time_t获得从19701.1的秒;

  tm为一个时间结构体;

  time(NULL);可以获得秒数;

  localtime_s();函数获得具体的年月日;不过得到的年要+1990才等于现在的年份;得到的月份要+1,才等于现在的月份;

  mktime();通过loacaltime()获得的时间转换成秒数;

 1 int main()    
 2 {
 3     time_t now=time(NULL);
 4     now += 3 * 24 * 3600;
 5     tm tmiof;
 6     
 7     localtime_s(&tmiof,&now);
 8 
 9     time_t p = mktime(&tmiof);
10     tmiof.tm_year += 1990;
11     tmiof.tm_mon += 1;
12     
13     system("pause");
14     return 0;
15 }

17. #define 原理:带入的文本,不是值,不会进行任何计算;

  只要将文本原翻不动的带入之后,检查语法是否正确,程序是否合理;

 1 #include <iostream>
 2 using namespace std;
 3 #define SUM 1+2
 4 int main()
 5 {
 6     int a = 4 * SUM;    //a=6 ,而不是12;
 7 
 8     system("pause");
 9     return 0;
10 }

解决办法:

 1 #include <iostream>
 2 using namespace std;
 3 #define SUM (1+2)
 4 int main()
 5 {
 6     int a = 4 * SUM;    //a=6 ,而不是12;
 7 
 8     system("pause");
 9     return 0;
10 }

#define 不建议使用,使用const常量进行代替,或者使用inline方法;    

 18.main 函数是可以有参数的,第一个参数是参数的个数;第二个参数是数组;

 1 int main(int a ,char* b[])
 2 {
 3     for (int i=0;i<a;i++)
 4     {
 5         printf("%s\n", b[i]);
 6     }
 7 
 8     system("pause");
 9     return 0;
10 }

这里的变量是通过cmd窗口进行赋值的;

·

19.atoi();函数;atof()函数;atol()函数;

 这个函数是将字符串转换成int型;float型;long型;

开始C++学习;

1.this指针:从内部访问其他成员时,不受public/private限制;

 使用隐含的this指针,来访问本对象的成员。

 this指针的地址和对象的地址相同;

 this指针是可以省略的;

 概括的是说this指针就是指向对象自己;;

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class m_class
 5 {
 6 public:
 7     void test();
 8     void set(int a,int b);
 9 private:
10     int x;
11     int y;
12     
13 };
14 void m_class::set(int a, int b)
15 {
16     x = a;    //this->x=a;
17     y = b;    //this->y=b;
18 }
19 void m_class::test()
20 {
21     printf("%d\n",x);//this->x
22 }
23 
24 int main()
25 {
26     m_class m;
27     m.set(12, 2);
28     m.test();
29     system("pause");
30     return 0;
31 }

2.采用“就近原则”。

在成员函数中的局部变量和局部变量重名时:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class m_class
 5 {
 6 public:
 7     void test(int x);
 8 
 9     int x;
10     int y;
11     
12 };
13 void m_class::test(int x)
14 {
15 //    printf("%d\n",x);       //输出结果为局部变量的x;
16     printf("%d\n",this->x);//输出的是成员变量的值x;
17 }
18 int main()
19 {
20     m_class m;
21     m.x = 1;
22     m.test(2);
23     system("pause");
24     return 0;
25 }


成员变量和全局变量重名时:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int x;
 5 class m_class
 6 {
 7 public:
 8     void test();
 9 
10     int x;
11     int y;
12     
13 };
14 void m_class::test()
15 {
16 //    printf("%d\n",x);  //打印的是成员变量的值;
17     printf("%d\n",::x);  //打印的是全局变量的值;
18 }
19 int main()
20 {
21     m_class m;
22     m.x = 1;
23     m.test();
24     system("pause");
25     return 0;
26 }

 3.inline一般放在声明函数或者定义函数之前;但是只有放在定义函数之前才有意义;

 作用是使的这个函数成为内联函数,相当于#define的方法,但弥补了宏定义的不足;、

 使用#define宏定义缺点:1.预处理器符号表的简单替换,无法参数有效性检查和不能享受编译器严格检查的好处;

         2.返回值不能强制转换成可转换的合适类型,存在隐患与局限性;

      优点:1.没有参数压栈,没有代码生成等一次系列操作,因此效率很高!

 使用inline内联的优点:1.函数代码被放入符号表里面,在使用时直接替换,像宏一样展开,没有调用的开销,效率高;

            2.弥补了#define的不足,编译器在调用内联函数的时候,会有一系列的检查正确性与安全性,消除了隐患和局限性;

          缺点:如何一个函数太复杂,那就是不适合作为一个内联函数,因为是以代码膨胀为代价的;

4.构造函数:不需要显示调用,而是在创建这个类的时候隐式的调用了这个构造函数;

     1.函数名与类名相同,没有返回值;

     2.用于初始化对象;

     3.可以重载;

 

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class MyClass
 5 {
 6 public:
 7     MyClass()
 8     {
 9         printf("1");
10         x = 10;
11         y = 23;
12     }
13     MyClass(int x, int y)
14     {
15         printf("2");
16         this->x = x;
17         this->y = y;
18     }
19 private:
20     int x;
21     int y;
22     
23 };
24 
25 int main()
26 {
27     MyClass a;
28     MyClass b(1, 2);
29     system("pause");
30     return 0;
31 }

 

5.析构函数:当对象被销毁的时候就会被调用;

    1.不能被显示调用,在销毁的时候调用;

    2.函数名和类名相同,没有返回值,在函数名之前有“~”符号;

 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include "DataStore.h"
 3 #include <stdlib.h>
 4 #include <stdio.h>
 5 #include <string.h>
 6 
 7 DataStore::DataStore()
 8 {
 9     m_head.next = NULL;
10 }
11 
12 DataStore::~DataStore()
13 {
14     Student *next = m_head.next;
15     while (next)
16     {
17         Student *p = next->next;
18         free(next);
19         next = p;
20     }    
21 }
22 
23 void DataStore::Add_ds(Student *student)
24 {
25     Student* next = (Student*) malloc(sizeof(Student));
26 
27     next->ID = student->ID;
28     strcpy(next->name,student->name);
29 
30     next->next = m_head.next;
31     m_head.next = next;
32 }
33 
34 void DataStore::Show_all()
35 {
36     Student* next = m_head.next;
37 
38     while(next)
39     {
40         printf("id=%d,name=%s\n",next->ID,next->name);
41         next = next->next;
42     }
43 }

6.默认构造函数:构造函数没有任何参数或者有参数,但是所有参数为缺省值的构造函数;

  默认构造函数非常重要,因为如果没有默认构造函数,则不能定义一个数组对象;因此我们在定义类的时候一般都会定义一个默认构造函数;

7.当一个类中的成员变量为另外两个类的时候,他们的构造函数和析构函数是怎么个调用顺序的;  

  1.执行构造函数的顺序是:先顺序执行成员变量的构造函数,最后执行本类的构造函数;

  2.析构函数相反;

8. 类的初始化方法:a.在构造函数后面加“:”然后初始化变量;

          b.在构造函数里面初始化成员变量;

 1 class DataStore
 2 {
 3 public:
 4     DataStore();
 5     ~DataStore();
 6 private:
 7     int y;
 8     int x;
 9 };
10 
11 DataStore::DataStore():x(1),y(2)
12 {
13     printf("%d,%d",x,y);
14 }
15 
16 DataStore::~DataStore()
17 {
18 
19 }
 1 class  Child
 2 {
 3 public:
 4     Child(int x, int y)
 5     {
 6         printf("%d,%d\n",x,y);
 7     }
 8 private:
 9     int x;
10     int y;
11 };
12 
13 class DataStore
14 {
15 public:
16     DataStore();
17     ~DataStore();
18 private:
19     int y;
20     int x;
21     Child m_child;
22 };
23 
24 DataStore::DataStore():m_child(1,3),x(1),y(4)
25 {
26     printf("%d,%d\n",x,y);
27 }
28 
29 DataStore::~DataStore()
30 {
31 
32 }

9.delete/new

 1.申请一个对象的时候:int* p=new int (123);  //这里是将申请的对象初始化为123;

            delete p;            //j返回的是一个正常使用的对象;可直接使用成员;

            p=NULL;

 

            int *p=(int *)malloc(sizeof(int)*10);//申请的只是一块内存,不是对象;

            free(p);

            p=NULL;

    2.申请多个对象的时候:int * p=new int[1024];  //这里申请了1024个int型内存;

            delete [] p;

 3.对于class类型,必须使用new/delete来创建和销毁;

  在new对象的同时会调用构造函数,在delete时,会调用析构函数

   动态创建对象时,必须含有默认构造函数;

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 
 4 class Student
 5 {
 6 public:
 7     Student():x(0)
 8     {
 9         printf("Student:创建\n");
10     }
11     virtual ~Student()
12     {
13         printf("Student:销毁\n");
14     }
15 public:
16     int x;
17 };
18 
19 class VUQ:public Student
20 {
21 public:
22     VUQ()
23     {
24         printf("VUQ:创建\n");
25     }
26     ~VUQ()
27     {
28         printf("VUQ:销毁\n");
29     }
30 public:
31     int y;
32 };
33 
34 int main()
35 {
36 //    Student *p = new VUQ();    //创建一个子类对象,并创建一个父类指针指向子类;
37 //    delete p;
38 
39     Student *p = new VUQ[3];
40     delete[] p;
41 
42     system("pause");
43     return 0;
44 }

10.子类继承父类。

 1 class Student
 2 {
 3 public:
 4     int x;
 5     int y;
 6 };
 7 
 8 class Vuq:public Student
 9 {
10 
11 };
12 
13 int main()
14 {
15     Vuq b;
16     b.x = 10;
17     b.y = 20;
18     system("pause");
19     return 0;
20 }

  子类继承父类的全部(public/protected)成员;

11.当父类的一个成员函数需要子类重写时,需要在父类的成员函数之前添加声明 virtual

                              --------简称为“虚函数”。

  这样在调用父类的这个成员函数时,已经被子函数给重写了;

 1 #include <stdlib.h>
 2 #include <stdio.h> 
 3 
 4 class Student
 5 {
 6 public:
 7     virtual void test()
 8     {
 9         printf("Student...");
10     }
11 public:
12     int x;
13 };
14 
15 class Vuq:public Student
16 {
17 public:
18     void test()
19     {
20         printf("VUQ.......");
21     }
22 public:
23     int y;
24 };
25 
26 int main()
27 {
28     Vuq b;
29     Student *c = &b;
30     
31     c->test();
32 
33     system("pause");
34     return 0;
35 }

12.子类对象构造时,先执行父类构造函数,在执行子类构造函数;

  子类对象析构的时候,和构造函数的方式相反;

  此外还可显示的调用构造函数;代码如下:

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 
 4 class Student
 5 {
 6 public:
 7     Student():x(3)
 8     {
 9         printf("Student:创建\n");
10     }
11     Student(int x)
12     {
13         this->x = x;
14         printf("Student:创建---2\n");
15     }
16     ~Student()
17     {
18         printf("Student:销毁\n");
19     }
20 public:
21     int x;
22 };
23 
24 class VUQ:public Student
25 {
26 public:
27     VUQ():Student(1)
28     {
29         printf("VUQ:创建\n");
30     }
31     ~VUQ()
32     {
33         printf("VUQ:销毁\n");
34     }
35 public:
36     int y;
37 };
38 
39 int main()
40 {
41     {
42         VUQ b;
43     }
44     system("pause");
45     return 0;
46 }

 13.在创建子类对象的时候,需要将父类的析构函数之前添加一个“virtual”声明;否则在销毁对象的时候,子类的析构函数将有可能无法执行;

  构造函数不能添加virtual声明!!!!!!!!!!!!!!!!!!!

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 
 4 class Student
 5 {
 6 public:
 7     Student()
 8     {
 9         printf("Student:创建\n");
10     }
11     virtual ~Student()
12     {
13         printf("Student:销毁\n");
14     }
15 public:
16     int x;
17 };
18 
19 class VUQ:public Student
20 {
21 public:
22     VUQ()
23     {
24         printf("VUQ:创建\n");
25     }
26     ~VUQ()
27     {
28         printf("VUQ:销毁\n");
29     }
30 public:
31     int y;
32 };
33 
34 int main()
35 {
36     Student *p = new VUQ();
37     delete p;
38 
39     system("pause");
40     return 0;
41 }

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 
 4 class Student
 5 {
 6 public:
 7     Student()
 8     {
 9         printf("Student:创建\n");
10     }
11      ~Student()
12     {
13         printf("Student:销毁\n");
14     }
15 public:
16     int x;
17 };
18 
19 class VUQ:public Student
20 {
21 public:
22     VUQ()
23     {
24         printf("VUQ:创建\n");
25     }
26     ~VUQ()
27     {
28         printf("VUQ:销毁\n");
29     }
30 public:
31     int y;
32 };
33 
34 int main()
35 {
36     Student *p = new VUQ();
37     delete p;
38 
39     system("pause");
40     return 0;
41 }

 

 14.纯虚函数/抽象类的是实际用途:充当“接口规范”:但是遵循此规范的类,都必须实现制定的函数接口。通常是一系列接口!

 15.拷贝构造函数的调用:

  1.定义对象:object a;

        object b(a);   //object b=a;

  2.动态创建对象:object a;

          object* p=new object(a);  

  3.函数的传值调用:void test(object obj);

  自己写的拷贝构造函数必须对每一个变量进行初始化;

  如果没有写拷贝构造函数,则编译器会自动生成拷贝构造函数。

 16.深度拷贝:在深度拷贝的时候,需要自己创建拷贝构造函数;

 1 #define  _CRT_SECURE_NO_WARNINGS
 2 #include <stdlib.h>
 3 #include <stdio.h>
 4 #include <string.h>
 5 
 6 class Student
 7 {
 8 public:
 9     Student(const char* str)
10     {
11         m_size = sizeof(str) + 1;
12         m_buf = new char[m_size];
13         strcpy(m_buf,str);
14         printf("%s\n", m_buf);
15     }
16     Student(const Student& obj)                //
17     {
18         this->m_size = obj.m_size;
19         this->m_buf = new char[this->m_size];
20         strcpy(this->m_buf, obj.m_buf);
21         printf("this is a copy");
22     }
23     ~Student()
24     {
25         delete[] m_buf;
26     }
27 
28 public:
29     int m_size;
30     char *m_buf;
31 };
32 int main()
33 {
34     Student objx("nihao");
35 
36     Student objy(objx);
37 
38     system("pause");
39     return 0;
40 }

 

 

 

 17. 友员:friend:在A类中,使用friend关键字对一个全局函数或者一个类声明为“朋友”。这样该函数或者该类便可以不受访问修饰符的限制进行访问A类的成员;

    原则上讲,该函数、类知识这个类的”朋友“,并不是“成员”

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

class Student
{
    friend void test(Student* obj);
private:
     int m_size;
};
void test(Student* obj)
{
    obj->m_size = 10;
}
int main()
{
    Student obj;
    test(&obj);
    system("pause");
     return 0;
}

 

 18.重载算术操作符;

  1.类操作符; 

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

class SUM
{
public:
    SUM(){}
    SUM(int a, int b)
    {
        num = a;
        result = b;
    }
    SUM operator + (const SUM& a)
    {
        SUM b;
        b.result = a.result + this->result;
        b.num = a.num + this->num;
        return b;
    }
public:
    int num;
    int result;
};

int main()
{
    SUM s(1, 4);
    SUM u(2, 4);
    SUM m =SUM (s + u);

    system("pause");
    return 0;
}

 

  2.重载全局操作符

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

class SUM
{
public:
    SUM(){}
    SUM(int a, int b)
    {
        num = a;
        result = b;
    }

public:
    int num;
    int result;
};

SUM operator + (const SUM& a, const SUM& c)
{
    SUM b;
    b.result = a.result + c.result;
    b.num = a.num + c.num;
    return b;
}

int main()
{
    SUM s(1, 4);
    SUM u(2, 4);
    SUM m =SUM (s + u);

    system("pause");
    return 0;
}

  19.类型转换操作符 “()”;

  一般形式:

 

class Object
{
public:
    operator type()
    {
        type result;
        return result;
    }
};

 

E.g:

 

 

 

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

class My
{
public:
    My(int x,int y)
    {
        this->x = x;
        this->y = y;
    }
    ~My()
    {
    }
    operator double()
    {
        return (double)x/y;
    }
public:
    int x;
    int y;
};
int main()
{
    My p(1,2);
    double z = (double)p;
    printf("%lf\n",z);
    system("pause");
    return 0;
}

 

20.重定义输入输出操作符“<<”和“>>”;

  

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class Point
{
public:
    int x, y;
};

// 日志类
class Logger
{
public:
    Logger()
    {
    }

    Logger& operator << (int value)
    {
        printf("%d", value);
        return *this;
    }
    Logger& operator << (double value)
    {
        printf("%f", value);
        return *this;
    }
    Logger& operator << (const char* value)
    {
        printf("%s", value);
        return *this;
    }
    Logger& operator << (const Point& point)
    {
        printf("(%d,%d)", point.x, point.y);
        return *this;
    }

    Logger& Print(const char* value)
    {
        printf("%s", value);
        return *this;
    }
    Logger& Print(const Point& point)
    {
        printf("(%d,%d)", point.x, point.y);
        return *this;
    }
};

int main()
{
    Logger lg;


    Point pt;
    pt.x = 12;
    pt.y = 13;
    //lg << 1 << "," << 11.01 << "hello" << pt << "\n";


    lg.Print("hello").Print("world");
    return 0;
}

 21.内部类:外部类对内部类没有任何特权,既不是父子关系,也不是继承关系; 

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

class Object
{
public:
    class VUQ
    {
    public:
        int num;
    };
private:
    int member;
};
int main()
{
    Object::VUQ a;
    a.num = 10;
    printf("%d\n",a.num);
    system("pause");
    return 0;
}

 

内部类的作用:避免类名重复;

如果一个类只有模块内部使用,则可以实现类名隐藏;

22.namespace:名字空间

 终极解决命名重复问题的方法;

 1.使用语法:

namespace xxx
{
    class yyy
    {

    };
}
这样在调用yyy类的时候需要在类之前添加xxx::yyy;
int main()
{
    xxx::yyy a;
    system("pause");
    return 0;
}

 

 使用using namespace xxx;

 则在使用xxx里面的成员是,不需要在调用前添加xxx::前缀了;  

23.函数模板

 template <typename T>

 使用时使用"<>"制定类型;

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>

template <typename T>

T M_max(T* arr,int len)
{
    for (int i = 0; i < len; i++)
    {
        if (arr[0]<arr[i])
        {
            arr[0] = arr[i];
        }
    }
    return arr[0];
}

int main()
{
    int arr[] = {0,1,2,10};
    int result = M_max <int> (arr, 4);
    system("pause");
    return 0;
}

 

24. 类模板

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

template <typename T>
class ArrData
{
public:
    ArrData():m_object(4),m_size(0)
    {
        m_buf = new T[m_object];
    }
    ~ArrData()
    {
    }
    void PushBack(T val)
    {
        if (m_size >= m_object)
        {
            resize();
        }
        m_buf[m_size] = val;
        m_size++;
    }
private:
    void resize()
    {
        int n = m_object + 4;
        T* buf = new T[n];
        memcpy(buf, m_buf, sizeof(T)*m_object);

        delete[] m_buf;

        m_buf = buf;
        m_object = n;
    }
private:
    int m_size;
    int m_object;
public:
    T* m_buf;
};

int main()
{
    ArrData<double> a;

    a.PushBack(1.2);
    a.PushBack(2.0);

    system("pause");
    return 0;
}

25.STL:标准模板库(vector,list,map,string)

 一般使用方法:#include <vector>

 名字空间STL使用名字空间std,

 因此使用:using namespace std;   

 26.vector的使用:vector<T>::iterator  //list内的迭代器;

  类似于数组,支持顺序访问,支持随机访问;

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <string.h>
using namespace std;

int main()
{
    vector<int> arr(18);
    int size = arr.size();
    int capacity = arr.capacity();

    arr.clear();

    int size1 = arr.size();
    int capacity2 = arr.capacity();

    arr.push_back(99);
    arr.push_back(22);

    vector<int>::iterator iter;                        //// 迭代器遍历
    for (iter = arr.begin(); iter != arr.end(); iter++)
    {
        int& value = *iter;
        printf("%d, ", value);
    }

    system("pause");
    return 0;
}

 

 27.STL库之list函数:list<T>::iterator  //list内的迭代器

 类似于链表,支持顺序访问,不支持随机访问;

 

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <list>
using namespace std;
class object
{
public:
    object(int id,char* str)
    {
        this->id = id;
        strcpy(this->name, str);
    }
    object()
    {}
    ~object()
    {}
public:
    int id;
    char name[20];
};
int main()
{
    list<object> st;
    st.push_back(object(1, "weiyouqing"));
    st.push_back(object(2,"liyu"));
    st.push_back(object(3, "zhangzhengyang"));

    list<object>::iterator ite;

    for (ite=st.begin();ite!=st.end();ite++)
    {
        object& value = *ite;

        if (value.id == 3)
        {
            st.erase(ite);
            break;
        }
    }

    for (ite = st.begin(); ite != st.end(); ite++)
    {
        object& value = *ite;
        printf("%d,%s\n", value.id, value.name);
    }
    system("pause");
    return 0;
}

 

 28.string.

 注意#include<string>是STL标准库里面的;

   #include<string.h>是c标准库里面的;

以下几种定义方式都是正确的:

 string str1("nihao");

 string str2="nihao";

 string str3 ("nihao",3);

 string str4;

 string str5="";

注意错误:string str6=NULL;

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string>

using namespace std;

int main()
{
    string s;
    s = "nihao";
    printf("%s\n",s.c_str());

    string s1("weiyouqing");
    int len = s1.length();
    s1.append(" nihao");
    printf("%s\n", s1.c_str());
    s1.clear();
    printf("%s\n", s1.c_str());
    int size =s1.size();
    printf("%d\n", size);
    s1.resize(1000);
    printf("%d\n", s1.size());

    string s2 = "nihao";
    s2[0] = 'N';
    s2.at(1) = 'I';
    printf("%s\n", s2.c_str());

    if (s2 == "NIhao")
    {
        printf("Is Equal\n");
    }
    else
    {
        printf("Is Not Equal\n");
    }

    string s3 = "weiyouqing";
    int y=s3.find('y');
    printf("%d\n", y);

    int y1 = s3.rfind('y');
    printf("%d\n", y1);

    string t6 = s3.substr(2, 3);
    printf("%s\n", t6.c_str());

    system("pause");
    return 0;
}

 

posted @ 2018-05-25 19:33  唯一诺  阅读(440)  评论(0编辑  收藏  举报