c语言里的指针。
指针是干嘛的?地址用来存放变量,指针就是指向这些地址的。
也就是指针就是地址。
一个地址内的变量可以任意变化,但是存放的地址的号不变。
举个栗子:你家在郑州市惠济桥某某,突然某天你家进来个二次元美少女并且成了你老婆,你们还生了几个娃。你家人是不是变多了。但是你家的房子还是20平,你家的位置大小不会因为你多了个老婆或者几个孩子而变化,这就是地址。(你不努努力换个100平的)
指针是指向地址的变量
指针变量 要加一个特殊符号*
例 int *p;定义一个整型指针变量 指针变量是p 而 int *是一个变量类型,整型指针变量
给它赋一个地址 p=&a;
p不能赋值 进行赋值的时候 *p=&a是错误用法;
这个东西就相当于取出指针变量指向的地址例如:
int a=10;int *p=&a;
printf("%d",*p);
输出的结果是 10 ,因为p指向的地址是a。
指针变量的运算是有限的,只能进行赋值、加减和关系运算。
以上对指针变量的操作都是合法的,在使用LCD液晶屏的时候经常会确定显示地址,用到指针就会很方便。
指针变量指向数组或字符串时可以进行加减运算,这时的+1,或-1会跟其数组内的变量的不同而不同,并不是+1就代表地址+1.因为int \char类型所分配的字节长度是不一样的。
指针变量的+1指的是移向下一个变量的地址。比如指针p指向数组a首地址,p+1指的是a[1].
关系运算:
这里指的是同一个地址序列的,比如&a[0]和&a[10]比,拿北京和固始县比没有任何意义
而且进行比较只是比较谁的位置高,谁的位置低
像我是个菜鸟,我肯定是跟跟我同样环境下的菜鸟比,
如果我去跟清华、北大的比知识只会显得自己狠呆
我们应该努力提高自己的水平,当自己从一个菜鸟变成一个萌新,那我们就可以站在萌新堆里与萌新里的大佬比较,只有下一刻比现在更好,我们才能跳出永远是一个菜鸟的境地。
赋值空值
可以直接对指针变量赋值0
例 int *p=0;这时的p不指向任何地址
指针与数组的用法:
这样定义后指针ptr就得到了数组的首地址
这时ptr就叫做指向数组的指针变量
下面说几种等价关系:ptr+1等价于a+1等价于&a[1]
如果用上这个符号*
就有以下关系 *(ptr+1)等价于*(a+1)等价于a[1];就是地址处存放的变量值(这是一维数组特有的)
我当初刚学的时候就把*认作是取值符号,但是指针变量p又不单单指向某一个变量的地址,还能指向指针变量和函数的入口地址。如果是函数的入口地址,这时候的意思是不是就不是取值了
写到这,听到Eye-Water (From "Attack on Titan")这首歌,真是感触颇深。我还是个菜鸟……
访问数组元素的总结
这里要提到为什吗在用到库函数scanf()时要在%d,后面加个&a了。因为你之前定义的变量,系统给它分配了地址。a只是作为一个变量名称就像你加张三他叫李四,真正区分你俩的是你俩社会关系的总和。要给a赋值,就要到a的地址上去,&符号叫做取址符。
再把上面的讲清楚一点
例如
int a[10];
int *p=a;
p++;
这里p++指的是变量a的首地址加一个整型变量所占的字节数;
#include<stdio.h>
#include<string.h>
#include<math.h>
//
int main()
{
//思路:
int a[10];
int *p=a;
p++;
printf("%8d%8d\n",a,p);
return 0;//今天又是没带return 0的一天
}
可以清晰的看见整型变量的地址差为4,这里为什莫是6422000,这是由于系统随机分配的
重头戏多维数组(以二维数组为例,平常也用不到更高的,再加上我的水平有限):
二维数组的地址是怎末存的呢
按行按列存的,在定义二维数组时可以不定义行数,但是必须定义列数,一维数组里如果有元素也可以不定义数组大小
例 int a[]={0,0,0,0,0,9,9};系统会自动确定数组大小的
int a[][3]={{0,2},{5},{23,2,3}};系统会知道数组三行三列,并且a[0][1]=2;a[1][1]=0;未赋值的变量会自动补0
下面回到地址
这里的*符号是对后面整个进行操作而不是对括号里的单独操作。用代码运行来验证
在二维数组里*号只能用来取数组的地址了
#include<stdio.h>
#include<string.h>
#include<math.h>
//
int main()
{
//思路:
int a[3][3]={{3,2},{2},{5,3,1}};
int *p=a;
printf("%8d%8d%8d%8d\n",a,*(a+1)+2,*(*(a+2)+1),**(a+2)+1);
return 0;//今天又是没带return 0的一天
}
指针的学习其实很需要实践,去试不同的用法
看上面代码的取值,要先取出地址,再加一个*号才是取值
第4个输出的是第3行首地址的值+1等于5+1=6;与第3个输出取第三行第二列的地址处的值3
这里是不一样的
与一维数组不同,一维数组加一个*号是就取值了,这里千万不能搞混,多试几遍。晕车了的话,后面会更迷糊。
二维数组加一个*号是取地址。并且加了括号内的取得是行地址,加外面的列地址
这个图里取得是二维数组第i+1行j+1列的地址
这里看着a[i]像不像一个变量,那是一维数组里的。二维数组的a[i]代表着行地址
a[i][j]才代表这个地址的值。