C++-自整理笔记

本文是关于C++编程的个人整理笔记,涵盖了C++的基础概念、指针常量与常量指针的差异、数据传递方式以及流(I/O)的操作。详细解释了如何使用指针常量和常量指针,以及const修饰引用和成员函数的用法。此外,还介绍了模板的使用,包括模板函数、多类型模板函数、模板函数的重载以及类模板的实现。文章通过实例展示了模板在减少代码重复和提高效率方面的作用。
摘要由CSDN通过智能技术生成

/**********************************************************************
 C++自整理笔记
***********************************************************************/
//1. 概念性的东西

//1) C++ 是由AT&T贝尔实验室的Stroustrup开发的。

//2) iostream.h等同于stdio.h(属于C),若要使用printf()/scanf(),需要stdio.h

//3) C语言中变量的声明需要放在程序或代码块头。C++中可任意放。

//4) C和C++当中,不带参数函数的区别
 int fun(); // 在C中表示可以取0个或多个变量;在C++中表示不需要转入变量。

//5) 符号化常量的地址不能赋予一个指针:
 Pointer = &number; // it’s wrong, cause const char number
//const常量地址只能赋予常量指针:
 const int x;
 const int *cpointer;
 int *pointer;
 cpointer = &x; //right
 pointer = &x; //wrong
//const指针传入函数,表示函数不能改变传入的值。
 int lookup(const char*ar,int len)

//6)    结构
 Struct book
 {
  Char title[80];
  Float price;
 }
 Struct book mybook  //C语言写法(个人推荐这样写,比较明了)
 Book mybook;    //C++写法

//注:枚举的声明和结构一样
 
//2. 指针常量和常量指针

//1)指针常量可以通过指针改变变量的值
 Int x = 2;
 Int * const point = &x;
 *point = 4; //now x = 4
 
 void main()
 {
  char * const str = "china";
  *str = "yangzhou"; // right 可以修改字符串的内容
  str = "another";             // wrong
 }
 
//2)常量指针不可以
 Int x = 2;
 Const int * point = &x;
 *point = 4; // wrong
 
 void main()
 {
  const char * str = "china";
  *str = "yangzhou"; // wrong
  str = "another";             // right 修改指针指向另一个字符串
 }

//3)上面两个例子看起来头疼吧,教你一个好方法;
//指针常量中,const用来修饰str,故str不能改变;
//常量指针中,const用来修饰*str,故*str不能改变。

//4)两种方法的组合,使地址和内容都无法改变
 void main()
 {
  const char * const str = "china";
  *str = "yangzhou"; //wrong
  str = "another";     //wrong
 }

//5)const修饰“引用”,使“引用”不可修改。
 void main()
 {
  int x = 20;
  const int &rx = x;
  rx = 2000; //wrong
 }

//6)声明函数时若在末尾加const,表示在该成员函数内不得改变类变量
 class myclass
 {
  char * str;
  myclass()
  {
     str = new char[64];
  }
  ~myclass()
  {}
  char fun(char nstr) const
  {
     str = "china";//wrong
     return str;
  }
 }

//7)数据传递给函数的方式默认是值传递,但如果一个函数被调用的次数过多,那就会
//产生很多个拷贝,造成效率不高,故我们可以使用“引用”,但“引用”带来的隐患是它可
//能修改变量的值,为此,我们可以使用“const引用”
 int ReturnInt(const int &);
 void main()
 {
  int i=10;
  ReturnInt(i);
 }
 int ReturnInt(const int &nInt)
 {
  nInt++;//wrong
  return nInt;
 }
           
//3)流(I/O)
 cin>>var1;
 cout<<var1<<endl;
 //转义字符:/a、/b、/f、/n、/r......(自己去查吧)
 int x;
 cin>>hex>>x;//将输入的x定性为十六进制数,并转换成十进制
 cout<<x;//假如输入64,那这里=100
 //dec:十进制       hex:十六进制      oct:八进制
 //参数化I/O操作符
 //首先需要 #include <iomanip.h> (Setbase似乎用不了,不知道它需要的头文件的名称)
 Setbase(int):   //设置换算格式(8/10/16)
 SetW(int):   //设置字段距离
 Setprecision(int);  //设置浮点数精度
 Setfill(int);    //设置填空字符
 Setiosflags(long); //设置输出字段的格式位
 resetiosflags(long);//复位输出字段的格式位
 
 Setiosflags(ios::showpos)<<100<<endl;
 //输出+100;showpos:在正数前面使用"+"号,更多的格式保存在一个枚举里面,自己去查吧!
 
 //更多的I/O函数
 getline //读一整行
 cin.getline(aLine,40,'t');//读到't'终止
 gcount //统计输入的字符个数
 ignore //忽略输入流中的字符
 
//get/put
 void main()
 {
  char aChar;
  aChar = cin.get();
  while(aChar!='n')
  {
     cout<<aChar<<endl;
     aChar = cin.get();
  }
 }
 
 void main()
 {
  char aChar = 'A';
  cout.put(aChar);
 }
 
//还有许多其它函数,请自行查阅

 

 

 

 /**********************************************************************
*  <模板>                                                                                             
*模板是一种参数化的类或函数,也就是类的形态或者函数的形态可以被参数改变.
***********************************************************************/

/**********************************************************************
*  <模板函数>  */                                                                                            

 template <class T> T funname(para type)

/*自我理解:
*       如果要计算int型和float型数组的平均值,可以分别写int_average(int nVal,*int size)和
*float_average(int nVal,int size)两个函数,但其实它们里面的步骤是一*样的,只是数据类型
*不同,如果使用模板,就不需要这么麻烦了。
***********************************************************************/
//例1:
 template <class T> average(T *array,int size)
 {
  T sum = 0;
  for(int i=0;i<size;i++)
   sum += array[i];
  T avg = sum/size;
  return avg;
 };
//"<class T>"告诉编译器"T"是函数使用的数据类型。

//提示:模板函数最好写在头文件中,但必须要写在main()前面

//例2:
 template <class T>
 T max(T x,T y) //传入的参数改必须是同类型的
 {
  return (x>y)  ? x:y;
 }

 void main()
 {
  double a = 50.235;
  double b = 50.234;
  double c = max(a,b);
  cout<<"最大值="<<c<<endl;
 }

//函数模板经实例化所生成的具体函数叫"模板函数";
//例如例1,可以实例化成 average(int,int)、average(float,float)、average(char,char) 等等...
//每一个模板形参前必须有"class"关键字!
//在template语句与函数模板语句之间不允许有别的语句;


/**********************************************************************
*  <多类型模板函数> 
*
*       如上题数组,若数组中所有元素之和超过类型范围怎么办?可用多类型*函数模板解决
***********************************************************************/
//例:
 template <class T1,class T2>
 T1 average(T1 *array,T2,int size)//声明函数模板
 {
  T2 sum = 0;  
  for(int i=0;i<size;i++)
   sum+=array[i];
  return(sum/i);
 }
 void main()
 {
  __int16 intArray[]={10000,20000,30000}; // 范围 -32768 - 32767
  cout<<"整数平均值="<<::average(intArray,3)<<endl;
 }

/* 自我理解
    此例中,当T1接收了__int16 intArray[]后,它俨然就成了__int16型了,但要命的是,数组中的
数字相加后,会超界,so...再定义一个T2,用T2来接收相加后的的数据,T2会根据数据的大小来
确定自己的类型。 */


/**********************************************************************
*  <模板函数的重载> 
*       因为模板函数需要接收同类型的参数,要是参数类型不一致怎么办?可以使用函数重载.
***********************************************************************/
 template<class T>

 T max(T x,T y) //传入的参数改必须是同类型的
 {
  return (x>y) ? x:y ;
 }

 int max(int x ,char y) //重载函数 max,一个整型参数,一个字符型参数
 {
  return (x>y) ? x:y ;
 }

 void main()
 {
  int a = 55;
//     int b = 66;
  char b = 'A'; //ASCII 码 65
  cout<<"最大值="<<max(a,b)<<endl;  //此处将调用重载函数
 }


/**********************************************************************
*  <类模板> 
***********************************************************************/
 const int size = 10;
 template <class T>
 class stack
 {
  T stck[size]; //模板定义数组的数据类型
 public:
  //若成员函数中使用了模板,则此函数需要在类体外定义!!!
  void push(T ch); //模板定义形参类型
  T pop(); //模板定义返回类型
 };

 template <class T>  //注意:在类体外实现成员函数时的写法!!!
 void stack<T>::push(T ob)
 {
 }

 template <class T> //注意:在类体外实现成员函数时的写法!!!
 T stack<T>::pop()
 {
  T a = 0;
  return a;
 }
 void main()
 {
  stack<int> a; //对象的定义
  //stack<int> a,b;
  //stack<double> b;
 }

/**********************************************************************
*  <多参数类模板> 
* template <class T,T t> 或者 template <class T,int size>
*      参数的名字在整个模板的作用域内都有效,类型参数可以作用作用域变量的类型,数值型
*参数可以参与计算,就像使用一个普通常数一样(例如 cout<<t<<endl;)
***********************************************************************/
 //多参数模板
template <class T,int size> //第一个参数是类型,第二个参数是数值(必须是常量)
 class stack
 {
    T stck[size];
    public:
    void push(T x);
    T pop();
    void print()
    {
        cout<<size<<endl;
    }
 };

 template <class T,int size> //注意写法!!!
 void stack<T,size>::push(T x)
 {
 }

 template <class T,int size>  //注意写法!!!
 T stack<T,size>::pop()
 {
    T a = 0;
    return a;
 }

 void main()
 {
    stack<int,10> a1,a2; //合法,对象的定义

    int x = 100;
    stack<int,x> b1; //不合法,x必须是常量

    const int y = 100;
    stack<int,y> c1; //合法.

    a1.print();
 //    stack<double,5> b1,b2; //对象的定义
 }


/**********************************************************************
*模板总结:
*      模板提供了代码复用.在使用模板时首先要实例化,即生成一个具体的函数或类.函数模
*板的实例化是隐式实现的,即由编译系统根据对具体模板函数(实例化后的函数)的调用来进
*行相应的实例化,而类模板的实例化是显示进行的,在创建对象时由程序指定.
*
*      以前我一直以为模板的方法全部都是隐含为inline(内联,就是函数体定义在类之外,提高
*函数的执行效率)的,其实并非如此(Thinking C++[2]中有提到模板的non-inline function).所以
*我们一般在后缀为 .i 或者 .inl的文件中完成模板类方法的实现.
*例: //in temp.h                         //in temp.inl 
*  template<class T>    template<class T>
*  class Temp       void Temp<class T>::print()
*  {          {...}
*  public:
*   void print();
*  }
*  #include "temp.inl"
*
*语法检查
*     对模板语汇法的检查会被延迟到使用的时刻,而不像一般的类或函数在编译器读到时就
*检查,所以如果你定义了一个模板,且语法错误,但你却没有去用它,编译时不会报错.
*
*继承
*      模板类和普通的类一样,也可以有派生类.且它的基类和派生类既可以是模板类,也可以不
*是模板类.
* class Abase
* {...};
* template<classT>
* class A:public Abase
* {...};
***********************************************************************/
/*模板小练习*/
/*
template<class T>
T sum(T x,T y)
{
    return x+y;
}

void main()
{
    int a = 100;
    int b = 200;
    int c = sum(a,b);
    cout<<"总和="<<c<<endl;
}
*/

/*
template <class T1,class T2>
T1 average(T1 *x,T2 y,int size)
{
    T2 sum = 0;
    for(int i=0;i<size;i++)
    {
        sum += x[i];
    }
    return sum / size;
}

void main()
{
    __int16 array[] = {20000,10000,15000};
    __int16 val = ::average(array,0,3);
    cout<<"平均值="<<val<<endl;
}
*/

/*
template <class T,int size>
class stack
{
private:
    T size[100];
public:
    void push(T);
    T pop();
};

template <class T,int size>
void stack<T,size>::push(T ch)
{   
    cout<<"in the push area"<<endl;
}

template <class T,int size>
T stack<T,size>::pop()
{
    T a = 0;
    return a;
}

void main()
{
    stack<int,100> a;
    a.pop();
    a.push(100);
}
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值