C++指针

18 篇文章 1 订阅
15 篇文章 7 订阅

概念

有时你申请一个变量(如int x;),计算机就会随机给你分配一个空间,你可以在那个空间内改变数值。就像计算机给了一个叫做a的小房子,但是只能在里面放int类型的值。比如你输入x=-1,计算机首先会把小房子找到,然后把-1放在里面。(如果里面有其他值,就拿出来)

那这个小房子的地方在哪里呢,就存放在地址里。每一个变量都有一个地址(即是它在内存中的位置)。所谓指针就是一个箭头→,指向一个地址,然后这个地址里有一个值。

声明

在类型后加上星号(*)即可,当然指针也分类型的,即:

int* a;//一个指向int类型房子的指针a(当前还是随机值)
char* b;//一个指向char类型房子的指针b

如果你不知道类型,也可以用void* c;

int* a,b;

有些人要问了,如果写成上面那种形式的话,那a,b各是什么类型呢?

答案是a是int类型指针,b是int类型的普通变量。

所以通常申请指针这样写:

int *a,*b;

注意定义指针后指针会指向一个随机的位置,如果你对这个位置进行不正确的操作,就有可能发生内存错误。

操作

赋值

首先我们要学习一个取地址的运算符&,它可以获取变量的地址。有些小伙伴或许并不陌生了,因为我们平常输入的时候都会用到它:

scanf("%d",&x);

这个句子的意思就是找到x所在的地址,然后把输出的int值放在里面。
你甚至可以输出一个地址,用printf和格式控制符1或者也可以用cout输出,如:

int a;
printf("%p",&a);
cout<<&a;

运行结果:

输出

*a表示a指向的值。

#include<cstdio>
int main()
{
    int *a;
    *a=0;
    printf("执行 *a=0 后,\n");
    printf("指针的地址:  %p\n",&a);
    printf("指针指向的值: %d\n\n",*a);
    *a=1000;
    printf("执行 *a=1000 后,\n");
    printf("指针的地址:  %p\n",&a);
    printf("指针指向的值: %d\n\n",*a);
    //&a=1000的写法是错误的
}

运行结果:

加减操作

指针可不可以进行加减操作呢,我试了一下,答案是可以的。其实想起来很简单,把地址前移或后退一段地址,是可以的。

#include<cstdio>
int main()
{
    int a,*b;
    b=&a;
    printf("指针指向的地址:  %p\n\n",b);
    b=b+1;
    printf("指针指向的地址:  %p\n\n",b);
}

运行结果:

因为b指向的是一个int类型,这里就是相当于把b的地址后移一个int类型,就是4,所以我们结果看到的是0028FF48,而不是0028FF45

所以同理

#include<cstdio>
int main()
{
    bool a,*b;
    b=&a;
    printf("指针指向的地址:  %p\n\n",b);
    b++;
    printf("指针指向的地址:  %p\n\n",b);
}

运行结果:

bool类型大小为1,于是。。。

数组

以前我们操作通常都是酱紫。

#include<cstdio>
int n,a[100];
int main()
{
    printf("输入:\n");
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    printf("-------------------------\n");
    printf("输出:\n");
    for(int i=1;i<=n;i++)
        printf("%d ",a[i]);
}

学了指针,可以酱紫。

#include<cstdio>
int n,a[100];
int main()
{
    printf("输入:\n");
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",a+i);
    printf("-------------------------\n");
    printf("输出:\n");
    for(int i=1;i<=n;i++)
        printf("%d ",*(a+i));
}

运行结果:

指针应用

指针与数组

我们知道,当定义数组int a[100];时,系统会连续开10个空间,所以:

#include<cstdio>
int main()
{
    int a[100]={1,2,3,4,5,6,7,8,9,10};
    int *p;
    for(p=&a[0];p<&a[0]+10;p++)
        printf("%d ",*p);
}

运行中:

当运行到第一次for循环是,p指针指向a[0]的地址0x28ff10,其指向的值就是1。

重点&a[0]+10是什么意思?
就是a[0]的地址后移10位的地址,所以p小于&a[0]+10,本质上就相当于最初的输出的方法。其中a[0]也可以换做a,也就是数组的首地址。

#include<cstdio>
int main()
{
    int a[100]={100,200,300,400,500,600,700,800,900,1000};
    printf("%d\n",*a);
    printf("%d\n",*a+5);
    printf("%d\n",*(a+5));//这条语句与上条有区别
}

运行结果:

其中*a+5*(a+5)的意义不同,*a+5的意思是a指向的值加5,所以得到的是100+5=105.*(a+5)的意思是a的地址加5,也就是&a[5],指向的值是600.

指针与函数

有时指针可以看成一个数组。如:

#include<cstdio>
int n;
int sum(int *A){
    int _sum=0;
    for(int i=1;i<=n;i++)
        _sum+=A[i];
    return _sum;
}
int main()
{
    int A[100];
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&A[i]);
    printf("%d",sum(A));
}

运行结果:

函数指针

函数指针甚至还可以指向函数,但指针的参数要和原函数一样。
注意:函数指针必须加上括号,否则系统会以为你定义了一个int类型的指针。于是乎。。。

#include<cstdio>
int n;
int (*p)(int*);//这里是函数指针
//int *p(int*);//不能这样写
int sum(int *A){
    int _sum=0;
    for(int i=1;i<=n;i++)
        _sum+=A[i];
    return _sum;
}
int main()
{
    int A[100];
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&A[i]);
    p=sum;
    printf("%d",p(A));
    //也可以这样写:
    //printf("%d",(*p)(A));
}

运行结果:

结构体指针

首先关于结构体基础知识,请—>点击<—
声明结构体指针就直接在名称前加*即可,指向结构体成员有两种方法,以程序为例。

#include<cstdio>
struct node{int a,b;}x,*y;
int main()
{
    y=&x;x.a=123;x.b=987;
    printf("%d\n",(*y).a);//第一种写法,一定要加括号哦!
    printf("%d\n",y->b);//第二种写法,不要加星号哦!
}

运行结果:

双重指针

如下:

#include<cstdio>
int main()
{
    int a=100,*b,**c;
    b=&a;c=&b;
    printf("%p %p %p %p\n",&a,b,*c,&c);
    printf("%d %d %d\n",a,*b,**c);
}

运行结果:


  1. 参考百度
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值