理解指针的某些元素的概念
比如:int *p,a=3;
p=&a;
1.这里的p是指针变量,用来存放地址的变量,32地址线时内存大小为4个字节,64地址线内存大小为8个字节;
2.& 是取地址运算符,p=&a就相当于将p=a的地址的值(p存放的是地址)
3.*p就是取a地址的值(定义指针变量--> 类型名 *指针变量名称) 比如(int *p)
4.指针类型和指针所指向的类型
int *p的指针类型为int * (p是指针变量)
int *p的指针所指向的类型是int型,
5.地址是一种编号,是连续性的,是一种数据
指针变量的引用
1.使用变量性: printf("%d",a);
2.指针访问 : printf("%d",*p);(这里的*号是取值运算符,单目运算符,在定义指针是的*号只是单纯的声明这个是一个指针)
指针变量的运算:(+ - ++ --)4种运算,(根本上就是指针的偏移)
指针变量上存放的是一个地址,存放的地址之间又是连续的
比如:第一个地址为1000,那么下面地址为1001,1002,1003....
所以说这里你通过加一就可以指向下一个地址了(所以不存在其他的运算符)
指针变量的加减,以指针所指向的类型空间单位进行偏移
比如:char*p char类型 1个字节 p+1(指针变量的运算,这里表示指向下一个内存空间) --->地址增加1个字节
int*p char类型 4个字节 p+1(指针变量的运算,这里表示指向下一个内存空间) --->地址增加4个字节
double*p char类型 8个字节 p+1(指针变量的运算,这里表示指向下一个内存空间) --->地址增加8个字节
注:首地址:一段内存空间中第一个存储单位的地址.
指针变量的加减,以指针所指向的类型空间为单位进行偏移(理解好这两句话才可以更加容易理解指针和数组的关系)
一维数组和指针
比如说我定义一个数组 int a[5]={0,1,2,3,4} 这个数组名a就是这个数组的 首地址
1.a的类型是int * 指向数组的第一个元素,这里指向a[0]
2.a[0]的类型是int型
注意:这里数组的&a与a的区别
&a这个地址指向的是整个数组,&a的类型为 int(*)[5] ,
&a+1-->加了20(4*5)个字节,意思是一整个数组为一个单元进行偏移.
a(数组的名称)的类型为 int * a+1--->加4个字节//代码解释
2.访问数组元素
1.下标法
比如:a[1]....
2.指针法
比如:
for(int i=0;i<5;i++){
printf("%d\n",*(p+i));//p的地址是不会变的
}
这里的*(p+i)的意思是取p+1,p+2,p+3...的地址的值
也能写成
for(int i=0;i<5;i++){
printf("%d\n",*p++);//p的地址发生变化(区别)
}//这里的*p++,就是也是和上面*(p+i)一样的
问题:
1.为什么这里的p++不需要用括号括起来,这是因为++是双目运算符和*(单目运算符)的优先级一样,但遵守从右往左运算,先运算++后调用*;
2.*的优先级又比+的优先级高所以得加个括号,使其先运算里面再调用
注意:总所周知,定义数组 int a[5]={0,1,2,3,4},
除了可以用定义指针*p指向数组的第一个元素之外,
还有用数组名a指向a[0](数组的第一个元素)
(上面说过数组名a的类型是 int* ,指向数组的第一个元素.)
注意在这种情况下, 我们用指针法时只能用*(a+i),不能用*a++;
原因很简单:a时数组名,也是首地址,上面说过*a++会改变a的地址值,这就相当于把整个数组都改了
所以:数组名不能够随意改变,不能改变,会报错.
二维数组和指针