C++ 指针

1.数组指针:关键在于辨别一维地址和二维地址

例1:

#include<iostream>
using namespace std;
int main(){

    //思考角度的关键在于辨别是一维地址还是二维地址
    int v[2][10]={{1,2,3,4,5,6,7,8,9,10},{11,12,13,14,15,16,17,18,19,20}};
    int (*a)[10]=v;// 数组指针 ,指针指向10个元素的数组
                   // *a 相当于 数组名
    cout<<**a<<endl;// 输出1,**a 相当于*一维数组名,
    cout<<**(a+1)<<endl;       // 输出11,a+1 表示指针指向第二个元素,而一个元素是一个数组
                               //        所以(a+1)是第二个数组的首地址(二维地址),**(a+1)表示11
    cout<<*(*a+1)<<endl;       // 输出2, *a是第一个元素的地址,*a+1 是第二个元素的地址  *(*a+1)表示2
    cout<<*(a[0]+1)<<endl;     // 输出2, a[0]是第一个数组第一个元素的地址
    cout<<*(a[1]+1)<<endl;     // 输出12,a[1]是第二个数组第一个元素的地址
    cout<<a[0]<<endl;          // 输出v[0]首地址
    cout<<a[1]<<endl;          // 输出v[1]首地址





    int k[10] = {0,1,2,3,4,5,6,7,8,9};    //k是一维地址
    int (*p)[10];
    p = &k ;                              //p是指向数组的指针,*p=一维数组名,所以p=&地址名,所以p相当于是二维地址
    for (int i=0;i<10;i++)
        cout<<*(*p+i)<<'\t';              //*p 是一维地址   *p+i 是一维的不同地址    *(*p+1) 是不同的元素


    int nupt[][3]={{1,2,3},{4,5,6}};      //nupt 是二维地址
    int (*pp)[3];
    pp=nupt;                              //*pp相当于一维数组名,所以pp 是二维地址,可以如此赋值
    cout<<*(*(p+1)+2)<<endl;              // p是二维地址    *(p+1) 是一维地址      *(*(p+1)+2)是元素
    //这时,p指向元素1,p+1就指向元素4啦!
    //*(*(p+1)+2)就等价于a[1][2]这个元素值了。
    
    return 0;
}

结果:

1
11
2
2
12
0x7fff5a5a6b30
0x7fff5a5a6b58
0 1 2345 6 7891


例2:

#include<iostream>
using namespace std;
int main()
{
    int (*p)[10] = new int [5][10];    //p是二维地址,所以申请空间时应该申请的是二维数组
    int n=0;
    for (int i=0;i<5;i++){
        for (int j=0;j<10;j++){
            *(*(p+i)+j)= n ;
            n++;
        }
    }
    for (int i=0;i<5;i++){
        for (int j= 0;j<10;j++){
            cout<<*(*(p+i)+j)<<'\t';
        }
        cout<<endl;
    }

    return 0;
}

结果:

0 1 2 3 45 6 7 8 9
10 11 1213 14 15 16 1718 19
20 21 2223 24 25 26 2728 29
30 31 3233 34 35 36 3738 39
40 41 4243 44 45 46 4748 49


2.基类指针,派生类对象与虚函数

#include <iostream>
using namespace std;
class Rect{
    float  L,W;
public:
    Rect(float a=0,float b=0){L=a;W=b;}
    float Area(){ return  L*W;}
};
class Cub:public Rect{
    float H;
public:
    Cub(float a, float b, float c):Rect(a,b){ H = c;}
    float Area(){ return Rect::Area()*H;}
};

int main(){
    Cub c(2,3,4);
    Rect r(20,10),*Pr=&c;     //基类指针指向派生类对象
    cout<<r.Area()<<endl;
    cout<<c.Area()<<endl;
    cout<<Pr->Area()<<endl;   //基类指针指向派生类对象时,如果调用的函数不是虚函数,而按基类函数调用,所以这里输出2*3=6
                              //基类指针指向派生类对象时,如果调用的函数是虚函数,则按派生类的函数调用
    return 0;
}

结果:

200
24
6


3.strcmp函数+利用指针实现升序排序

strcmp函数实现字符串ASCII的比较,str1>str2返回1,str1==str2返回0,str1<str2返回-1。所以实现的不是按字符串长度的排序。


4.不用strcat函数库,实现字符串的拼接

#include <iostream>
using namespace std;
void fun1(char *str1,char *str2){
    int i=0;
    while(*str1++);    //当*str1='\0'时,while后,str1还是++了
    str1--;            //执行while后,在abc后的第二个0上,--后在abc后的第一个0上
    while(*str2++) i++;//i从0开始计算,代表了*str2的字符个数(不包括0)
    str2-=2;           //和上一个while类似,str2指在ABC的C上
    for(;i>0;i--)      //将str2反向接在str1的后面
        *str1++=*str2--;
}

void fun2(char *str1,char *str2){
    while(*str1++);
    str1-=2;                  //str1指针落在第一次拼接的abcCBA的A上
    while(*str1++=*str2++);   //str2正向拼接  得到abcCBABC
}

int main(){
    char A[10]="abc";
    char B[10]="ABC";
    void (*f) (char *,char *);
    f=fun1;
    f(A,B);
    cout<<A<<'\n';
    f=fun2;
    f(A,B);
    cout<<A <<'\n';
    return 0;
}

结果:

abcCBA
abcCBABC


5.结合性:先.后*

#include <iostream>
using namespace std;
class A{
    int *p;
public:
    A(){}
    A(int data){
        p = new int ;
        *p = data;
    }
    ~A(){if(p) delete p;}
    A(A &a){
        p=new int (*a.p+5);   //结合性先.后*
    }
    void print(){
        cout<<*p<<endl;
    }
};
int main(){
    A a(10);
    A b(a);
    b.print();
    return 0;
}

输出:

15








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值