C++学习-指针2

上一次对指针的学习

考试完了,继续

6. 引用类型与函数

6.1 引用类型

引用就相当于给变量取一个别名,声明应用类型的变量需要在变量名前加&,并且必须制定初值,此后不可再次赋值。当然,类型一般都是相同的。

//声明
int i;
int &j=i;

相当于i有了个别名'j'。

j也可以再次给其他引用变量赋予初值

int i;
int &j=i;
int &t=j;

就相当于i有了两个别名j,t.它们用的都是同一内存空间。
如果我们不想让 i 的值应用改变,可以申明一个引用类型常量

int i;
const int &j=i

这样我们可以通过 j 来引用 i ,但不能通过 j 给 i 赋值。

既然是引用常量,所以也可以给它一个常量

const int &j=2;

这样可以使用 j 但无法对其赋值。

6.2 引用传递

6.2.1 引用作为形参

void swap(int &a,int &b)
{
    int c;
    c=a;
    a=b;
    b=c;
}

调用swap(x,y),这样a,b分别作为x,y的“别名”完成交换,比指针方便得多。

6.2.2 返回应用的函数

int &index(int ,x);

这样返回的就是return后面变量的引用,同时可以作为左值来改变return 后面的变量。

7. 指针数组和多级指针

7.1 指针数组

指针数组,也就是每一个元素都是指针的数组,定义方式如下:

int *arr[12];//每个元素是指向整型的指针
char *str[3]={"123","456","abc"};//三个元素分别是指向"123","456","789"字符串常量(其实就是它们的首地址)的指针。后面会再次提及。

7.2 多级指针

多级指针,比如,指向整型的指针是一级指针,指向一级指针的指针是二级指针,指向二级指针的指针是三级指针,以此类推,定义如下:

int *a;
int **b;
int ***c;
……  

打个比方:

int x=10,*i,**j;
i=&x;
j=&i;

二级指针 j 存的是 i 的地址,所以 *j 的值就是一级指针 i 中储存的值,也是就 x 的地址,既然 *j 是 x 的地址,那么 **j 就是 x 的值,所以 **j==10。

对于之前举的例子:

char *str[3]={"123","456","abc"};

这是一个指针数组,里面3个元素存储的分别是三个字符串的首地址,所以:
str[0] 等于 *str 等于第一个字符串的地址,str[1] 等于 *(str+1)等于第二个字符串的地址 , str[3]同理。所以可以通过以下方式输出三个字符串:

for(int i=0;i<=2;++i)
    cout<<str[0];

7.3 动态二维数组

动态二维数组可以通过二级指针来实现:

#include<iostream>
using namespace std;

int main()
{
    int **a,i,j,k=0; //a是动态数组的名字

    a=new int *[3];     //申请指向每一行首地址的指针
    for(i=0;i<3;++i)
        a[i]=new int [4];       //为每一行申请空间,至此,动态二维数组建立完毕
    
    for(i=0;i<3;++i)        //喜闻乐见的赋值        
        for(j=0;j<4;++j)
            a[i][j]=k++;

    cout(i=0;i<3;++i){      //看看输出结果
        cout<<endl;
        for(j=0;j<4;++j)
            cout<<a[i][j];
    }

    for(i=0;i<3;++i)    //释放
        delete [] a[i];
    delete [] a;

    return 0;
}

这就很绕了,a里面的是a[0]的地址,指向a[0],a[0]存的是a[0][0]的地址,指向a[0][0]。

7.4 二维数组,二级指针的云云

想体会它们之间的玄( n )奇( m )奥( m )妙( l )可以看以下:

CSDN : 数组名不完全等于指针

博客园 : 二维数组名和二级指针

以上

8. 函数指针

8.1 指向函数的指针

函数指针也就是指向函数的指针,定义方式如下

返回类型 (*指针变量)(形式参数表);
//例如
int (*p1)();        //定义了一个没有参数,返回类型为int型的指针
double (*p2)(int);  //定义了一个指向整型参数、返回类型为double的函数指针

为了染指向函数的指针指向某一个特定的函数,可以通过赋值

指针变量名 = 函数名
//例如
int fuction() {;}    //定义函数名为 fuction 的函数
int (*p)();     //定义函数指针
p=fuction;   把函数 fuction 的入口地址赋给指针 p ,以后就能通过 p 来调用 fuction
//调用方式(以下三者等价):
p();
(*p)();
fuction();

8.2 函数指针作为函数参数

就是把函数指针作为参数啊,如下:

void sort(int a[],int size,bool (*f)(int,int));

这样做有什么意义?就是把函数的入口地址给 f ,然后通过f调用函数。
详细用例可以参考这篇博客:

函数指针的用法---以冒泡排序为例

8.3 指向函数的指针数组

定义方式的一个举例如下

void (*func[6])()={NULL,f1,f2,f3,f4,f5};

相当于定义了一个没有返回值的6个指向函数的指针,第一个让其指向地址0,其余5个分别指向五个函数的入口地址。

最后

在摸了在摸了
明天(26号)开始结构体。

posted @ 2020-11-25 23:01  七铭的魔法师  阅读(74)  评论(0)    收藏  举报