C++杂记

内存四区:代码区,全局区,栈区,堆区

## 引用'&'

给变量起别名。

注意:1.必须初始化 2.不可改变

引用的是堆区和栈区

    "&"符号进行引用:
    int a=10;(定义一个变量)
    int & b=a;(给b初始化,即为给a一个别名,而b也就是a)
    b=20;(给b赋值为20,也就是给a赋值为20)
    cout<<a<<b;(可看见a,b输出的值均为20)

C++ 函数可以返回一个引用,方式与返回一个指针类似。

##### 引用做函数的返回值

 注意:1. 不要返回局部变量的引用 2. 函数的调用可以作为左值

    可以用:static int a=10;即为静态变量,存放在全局区,其在程序结束才释放

##### 引用的本质

在C++内部实现是一个指针常量(即可以更改所指对象的值但不可以更改地址)

    int&p=a;
    就等价于:int *const p=&a;

##### 常量引用

作用:修饰形参,防止误操作。加const修饰形参,防止形参改变实参

## NEW

##### new的基本语法

    int *func()
    {
        int *p =new int(10)
    //堆区创建整型数据,new返回的是该数据的指针
    return p;
    }
    void test01()
    {
        int *p=func();
    cout<<*p<< endl;
    //在堆区 由程序员开辟 由程序员释放
    //释放数据 利用 delete即可
    delete p;//即已把p的值释放
    }
    int main()
    {
        test01();
    }
    

##### 利用new开辟数组

    void test02()
    {
       int*arr= new int[10];
    for(int i=0;i<10;i++)
    {
        arr[i]=i+100;
    }//给数组赋值
    for(int i=0;i<10;i++)
    {
        cout<<arr[i]<<endl;
    }//打印数组
    delete[]arr;//释放数组
    }
    int main()
    {
        teat02();
    }

## 指针

1. 使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。通过使用一元运算符 ***** 来返回位于操作数所指定地址的变量的值。

    #include <iostream>
     using namespace std;
     int main ()
    {
       int  var = 20;   // 实际变量的声明
       int  *ip;        // 指针变量的声明
       ip = &var;       // 在指针变量中存储 var 的地址
    
       cout << var << endl;
       // 输出在指针变量中存储的地址
       cout << ip << endl;
       // 访问指针中地址的值
       cout << *ip << endl;
       return 0;
    }
    当上面的代码被编译和执行时,它会产生下列结果:
     20
     0xbfc601ac
     20

##### 空指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为**空**指针。NULL 指针是一个定义在标准库中的值为零的常量。

    #include <iostream>  
    using namespace std;
    
      int main ()
      {  int  *ptr = NULL;
    
         cout <<  ptr ;    
         return 0;}
      } 
     // ptr 的值是 0
    //注意的是,空指针不可以访问

##### 指针递减递加

递加:从数组第一个开始

    int *ptr;
    ptr=array;
    cout <<*ptr;
    ptr++;

递减:

    int *ptr;
    ptr=&array[arraysize];
    cout <<*ptr;
    ptr--;

##### 指针的比较

指针可以进行大小比较,比如同一个数组中的不同元素。

## 数组

##### 二维数组

二维数组中的元素是通过使用下标(即数组的行索引和列索引)来访问。如:int val = a[2][3];

##### 指向数组的指针

数组名是指向数组中第一个元素的常量指针。e.g: double runoobAarray[50]; 其中**runoobAarray** 是一个指向 &runoobAarray[0] 的指针,即数组 runoobAarray 的第一个元素的地址(使用数组名作为常量指针是合法的。 p.s: 常量指针是指指针指向其地址但内容是不可改变的)。因此,下面的程序片段把 **p** 赋值为 **runoobAarray** 的第一个元素的地址:

    double *p;
    double runoobAarray[10];
    
    p = runoobAarray;

*(runoobAarray + 4) 是一种访问 runoobAarray[4] 数据的合法方式。

把第一个元素的地址存储在 p 中,就可以使用 *p、*(p+1)、*(p+2) 等来访问数组元素。

    #include <iostream>
    using namespace std;
    int main ()
    {
       double runoobAarray[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
       double *p;
       p = runoobAarray;
       // 输出数组中每个元素的值
       cout << "使用指针的数组值 " << endl; 
       for ( int i = 0; i < 5; i++ )
       {
           cout << "*(p + " << i << ") : ";
           cout << *(p + i) << endl;
       }
       cout << "使用 runoobAarray 作为地址的数组值 " << endl;
       for ( int i = 0; i < 5; i++ )
       {
           cout << "*(runoobAarray + " << i << ") : ";
           cout << *(runoobAarray + i) << endl;
       }
       return 0;
    }
    当上面的代码被编译和执行时,它会产生下列结果:
    使用指针的数组值 
    *(p + 0) : 1000
    *(p + 1) : 2
    *(p + 2) : 3.4
    *(p + 3) : 17
    *(p + 4) : 50
    使用 runoobAarray 作为地址的数组值 
    *(runoobAarray + 0) : 1000
    *(runoobAarray + 1) : 2
    *(runoobAarray + 2) : 3.4
    *(runoobAarray + 3) : 17
    *(runoobAarray + 4) : 50

##### 传递数组给函数

可以通过指定不带索引的数组名来传递一个指向数组的指针。当传数组给一个函数时,数组类型自动转换为指针类型,因而传的实际是地址。

##### 从函数返回数组

C++ 不允许返回一个完整的数组作为函数的参数。C++ 不支持在函数外返回局部变量的地址,除非定义局部变量为 **static** 变量。

如果想要从函数返回一个一维数组,必须声明一个返回指针的函数,如下:

    int * myFunction()
    {
    .
    .
    .
    }

## 字符串

字符串实际上是使用 **null** 字符 \0 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。

声明和初始化创建了一个 **RUNOOB** 字符串。由于在数组的末尾存储了空字符,所以字符数组的大小比单词 **RUNOOB** 的字符数多一个。

    char site[7] = {'R', 'U', 'N', 'O', 'O', 'B', '\0'};

依据数组初始化规则,可以把上面的语句写成以下语句:

    char site[] = "RUNOOB";

##### 注意:

如下代码段,当遇到字符中的数字时,想使用时要转换成int整数,利用:(str[i] - '0')的表示。

     string str;
        cin >> str;
        double  value1 = 0;
        for (int i = 0; i < str.length(); i++)
        {
            if (isdigit(str[i]))
           {
               int a = 0;
               value1 = ((str[i]-'0') * pow(16, str.length() - 1 - i));
           }

## 函数

1. setw() 函数: 用于设置字段的宽度,只对紧接着的输出产生作用。 setw(n), n 表示宽度,用数字表示。可以setfill()配合使用设置其他字符填充。setw和setfill 被称为输出控制符,使用时需要在程序开头写上#include "iomanip",否则无法使用。
  
2. C++ 中有大量的函数用来操作以 null 结尾的字符串:
  
  | 序号  | 函数 & 目的 |
  | --- | --- |
  | 1   | **strcpy(s1, s2);**<br>复制字符串 s2 到字符串 s1。 |
  | 2   | **strcat(s1, s2);**<br>连接字符串 s2 到字符串 s1 的末尾。连接字符串也可以用 + 号,例如:<br><br><br>string str1 = "runoob";<br>string str2 = "google";<br>string str = str1 + str2; |
  | 3   | **strlen(s1);**<br>返回字符串 s1 的长度。 |
  | 4   | **strcmp(s1, s2);**<br>如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回值小于 0;如果 s1>s2 则返回值大于 0。 |
  | 5   | **strchr(s1, ch);**<br>返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。 |
  | 6   | **strstr(s1, s2);**<br>返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。 |
  

##### 缺省值

即函数形参的默认值。

注意:1. 有默认值的往右写 2.如果函数声明有默认参数,函数实现就不能有默认参数。所以函数声明和实现只能有一个有默认值

##### 占位参数

函数的形参列表里可以有占位参数,但调用时必须填补位置

##### 函数重载

在同一个作用域下,函数名相同且类型、个数、顺序不同。注意:返回值不可以作为其条件

## I/O 库头文件

下列的头文件在 C++ 编程中很重要。

| 头文件 | 函数和描述 |
| --- | --- |
| <iostream> | 该文件定义了 **cin、cout、cerr** 和 **clog** 对象,分别对应于标准输入流、标准输出流、非缓冲标准错误流和缓冲标准错误流。 |
| <iomanip> | 该文件通过所谓的参数化的流操纵器(比如 **setw** 和 **setprecision**),来声明对执行标准化 I/O 有用的服务。 |
| <fstream> | 该文件为用户控制的文件处理声明服务。我们将在文件和流的相关章节讨论它的细节。 |

##### 标准错误流(cerr)

预定义的对象 **cerr** 是 **iostream** 类的一个实例。cerr 对象附属到标准输出设备,通常也是显示屏,但是 **cerr** 对象是非缓冲的,且每个流插入到 cerr 都会立即输出。

##### 标准日志流(clog)

预定义的对象 **clog** 是 **iostream** 类的一个实例。clog 对象附属到标准输出设备,通常也是显示屏,但是 **clog** 对象是缓冲的。这意味着每个流插入到 clog 都会先存储在缓冲区,直到缓冲填满或者缓冲区刷新时才会输出。

## 数据结构

C/C++ 数组允许定义可存储相同类型数据项的变量,但是**结构**是 C++ 中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。

定义结构,必须使用 **struct** 语句。struct 语句定义了一个包含多个成员的新的数据类型。

在结构定义的末尾,最后一个分号之前,可以指定一个或多个结构变量(也可以在main函数中定义变量)。

##### 访问结构成员

使用成员访问运算符: ' . '

##### 结构体作为函数参数

传参方式与其他类型的变量或指针类似。

##### 指向结构的指针

与定义指向其他类型变量的指针相似。把 & 运算符放在结构名称的前面。为了使用指向该结构的指针访问结构的成员,必须使用 -> 运算符。

##### typedef 关键字

## C++ 类 & 对象

关于类的碎碎念:

类定义了如何表示和控制数据。成员函数归类所有,描述了操纵类数据的方法。

cout.put()是一个成员函数。只能通过类的特定对象来使用成员函数,必须用句点将对象名和函数名称连接。句点被称为成员运算符。

##### C++类定义

以关键字 **class** 开头,后跟类的名称。类的主体是包含在一对花括号中。类定义后必须跟着一个分号或一个声明列表。

##### 定义 C++ 对象

类提供了对象的蓝图,基本上,对象是根据类来创建的。声明类的对象,就像声明基本类型的变量一样。

##### struct 和 class的dif

struct默认权限为公共;class默认权限为私有。

##### 封装

含义一:将属性行为作为一个整体,并加以权限控制。(一般属性用变量,行为用函数。)

含义二:类在设计时,可以把属性和行为放在不同的权限下,加以控制。访问权限有三种:public(公共), protected(保护), private(私有)。只有public在类内类外可以访问,其他的只能访问类内。

##### 构造函数

主要作用于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。语法如下:

    类名(){}

没有返回值也不写void;函数名和类名一样;可以有参数

##### 析构函数

主要作用于对象销毁前系统自动调用,执行一些清理工作。

    ~类名(){}

没有返回值也不写void;函数名与类名一样但是有“ ~ ”;不能有参数

##### 成员函数

成员函数可以定义在类定义内部,或者单独使用**范围解析运算符 ::** 来定义。(在 :: 运算符之前必须使用类名。)在类定义中定义的成员函数把函数声明为**内联**的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值