C语言的指针

先絮叨絮叨前言吧,反正基本上每个教过我C语言的老师,都跟我们说,指针是C语言最难的部分;不会指针=不会C语言;指针是重中之重;还有等等。。。今天上了一天的课,这指针给我的感觉就是一个字,绕,要记得知识量并不大,但特别绕,和山路一样,有时候真的能把你绕着绕着就绕晕了。

言归正传

指针

首先有两个知识点。
1—指针变量:专用于存放地址的变量
2—地址常量:内存地址
咱们后面慢慢解释这个

定义

格式:<存储类型> <指针类型>*<指针变量名>
一般写法:int * p ;

存储类型:auto , regist , static , extern

数据类型:取决于要指向的那个变量的数据类型,即目标数据类型

譬如有个int m = 10;你要定义一个指针指向这个m,则你指针的数据类型得为int,得跟着人家对得上型号。int * p = & m;在这里,p指向了m,p存储了m的地址,这时你可以写一条输出语句    
printf("p = %p ,&p = %p ,*p = %d",p,&p,*p);
p输出的是m的地址,&p输出的是自己地址,*p输出的是目标的值
进行归纳:
p   指针变量          内容    地址量
*p  指针所指向的对象   内容     数据
&p  指针变量占用的存储区域地址   常量

运算符

  1. *
    (1.类型的一部分
    (2.指针解引用
  2. &
    取地址
  3. +-
    指针的加减;加减的是单位长度
    单位长度:指针所指向的数据类型所占的字节数
  4. [ ]
    [ ]:指针加单位长度后,取内容运算
    a[i] <==> *(a+i)
    p[i] <==> *(p+i) //p是指针变量,a是地址常量

来点通俗易懂的说法,就像一把钥匙,继续拿int m =10;来说,定义一个指针 int p=&m,这时候你已经将m的地址交给了p了,然而并没什么用,你有了p的地址,但无法进入m中,知道m的详细信息,这时候就起到了至关重要的作用,只有当p有了的时候,就可以轻而易举的读取到m的详细信息,并且!还可以更改m的值;

还有一点,就是关于指针大小的问题,在32位操作系统中,指针大小一直是占4个字节,不会因为数据类型的改变而改变。

指针数组

本质是数组,元素是指针
格式: int *p[ 3 ];

int a = 10;
int b = 30;
int *p[2];
p[0] = &a;
p[1] = &b;

数组指针

本质是指针,专用于指向数组
格式: 数据类型(*p) [列数] ; int (*p) [ 3 ];
这里的列数也是格式,定义的指针必须匹配列数为3的二维数组

指针这章总结起来真的好难,知识点真心不知道该怎么讲,特别是对我这种最笨的人来说,讲一个知识点比做一个知识点还难。

今天有写了很多例题,我将例题进行分析好了,然后想到啥说啥

int a =10;
int * p =&a;
printf("p   =%p\n",p);      //指针的加减:加减的是单位长度
printf("p+1 =%p\n",p+1);    //单位长度:指针所指向的数据类型所占的字节数           

int a[4] ={1,5,6,3};
int *p = a;
//输出a的地址
printf("a   =%p\n",a);
printf("a+1 =%p\n",a+1);
printf("p+2 =%p\n",p+2);
printf("p+3 =%p\n",p+3);
//输出a的值
printf("*(a+0)  = %d\n",*a);
printf("*(a+1)  = %d\n",*(a+1));        //a[i]  <==> *(a+i)
printf("*(p+2)  = %d\n",*(p+2));
printf("*(p+3)  = %d\n",*(p+3));

还记得数组那一章有个知识点么,数组名=数组的首地址,在这里,a = p
所有出现a的地方都可以用p来表示。

a[1] = p[1] = * (a+1) = * (p+1) (牢记)

int a = 10;
int b = 30;
int c[5] = {0,1,2,3,4};
int *p[3];
p[0] = &a;  
p[1] = &b;
p[2] = c;
printf("*p[0]   =%d\n",*p[0]);
prntf("*p[1]    =%d\n",*p[1]);  
printf("*c[3]   =%d\n", c[3]);
printf("*(p[2]+3)=%d\n",*(p[2]+3)); 
printf("p[2][3] =%d\n",p[2][3]);    

上面这几行代码是指针数组的一个应用,数组里每一个元素都代表的是指针,每个指针都关联到一个变量。譬如要打印c[3]的数据,因为指针p[2] = c,所以有三种写法。
c[3] = p[2][3] = * (p[2]+3)
这里就用到了上面要牢记的东西。

int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
printf("a[1][2]     = %d\n",a[1][2]);       //指针加单位长度后,取内容运算
printf("*(a[1]+2)   = %d\n",*(a[1]+2));
printf("*(*(a+1)+2) = %d\n",*(*(a+1)+2));

这里写了取数据的三种表达方式
a[1][2] = * (a[1] +2) = * ( * (a+1)+2)

最后还一个知识点,const
const有两种写法
1. const int * p =&a
2. int * const p = &a

第一种:const加在int前面时,没办法更换该门牌号里的东西了,即*p只能获取到a的值,不能改变a的值

第二种:const加在int * 后面,没办法更换门牌号了,即*p只能指向a,无法指向别的

真的好累。感觉脑壳要炸了。。。都怪以前没好好学习。明早起来再温习一遍。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值