针就是一种用来存储地址(地址指的就是数据在电脑的存储位置)的数据类型;就如int是存整数的,float,double用来存浮点数一样;
在c语言中,变量的声明格式为 数据类型|数据名|数据
指针也一样
数据类型:根据要取地址的数值的数据的类型,指针有相应的数据类型;
如若要被取地址的是int类型那么
指针就是 int* float 就是float*(类推)
数据名 遵守变量的命名规则即可;
数据:就如前文讲的指针的数据是地址,即数据在电脑中的存储位置,将电脑比作一栋楼,数据比作楼中的房客的话,地址很好理解,最重要的是通过一个数据的地址可以访问到这个数据.在c语言中地址用16进制表示.
&:
{
>_< : 那么如何取得一个数据的地址呢?
^_^ : 用&这个符号,如 int i=9; int* i_p=&i;&是一个一元运算符。他的作用就是取地址。
>_<:那么到底是怎么取地址的呢?电脑在读到&时候发生了什么?
^_^:每一个变量标识符在编译期间,编译器会为它们创建一个符号表,其中存放着变量标识符相应的各种属性,如类型.地址标识等,从这个符号表里找
>_<:那有这么多变量唉....每一个变量都要创建符号表不是很耗内存?电脑又是怎么从这么多变量中找到某个变量的?符号表中这么多数据每个又是存在那的?
=_=||:...........这个嘛.....你猜啊...在c中当定义一个变量并对其取地址的时候电脑发生了什么?
}
指针取地址之后我们称为指针指向某个物体;通过对一个指针*可以获得指针指向的数据的值。
(int i=9;int* i_p=&i;这样i_p就指向i);之后就可以通过*来获取到i的值;
(printf("%d\n%d",*i_p,i))会输出两个一模一样的值,不,该说是输出同一个值两次.仔细分析之.int i;声明变量int整数,分配地址.赋值9,将值9丢到地址中;int* i_p=&i;同样声明变量int指针,分配地址.赋值i的地址,将i地址丢到i_p的地址中.*i_p 就会得到i的值;
i_p:i的地址值;
*i_p:i的值;
&i_p:指针的指针值;
规则;
赋值:
求值:
求指针地址
给指针加上一个整数;(数组有意义)
求差值(数组有意义)
数组与指针;
int num[2]={1,2};
数组名的值也就是数组首个元素的地址值;
即printf("%p\n%p",num,&num[0]);输出是相同的
为什么呢?
当当...这就是指针存在的意义啊.
指针还有一个特性,即指针加上一个数相当于指针的数值+指针所指数据类型的字节数;
如
int num[2] = { 1, 2 };
printf("%p \n %p \n %d \n%d",num,num+1,*num,*(num+1));
显示为:00D8FD10
00D8FD14
1
2
计算机将数组存储在相邻的内存中,通过指针的这个特性,就可以通过指针的加减来获取数组的值;
比较复杂的是多维数组.但是原理还是同上的;
二维数组
int num[2][3]={{1,2,3},{4,5,6}};
数组名是数组首个元素的地址值;
num=&num[0];
但是num[0]同样也是一个数组
num[0]=&num[0][0];
另外二维数组指针的定义与普通指针不同
为什么呢?
因为数据类型不同,而数据类不同就不能正确的使用指针的特性.普通的指针 数据类型为int*每次指针加上一个数就相当于加4.但这样是没有办法通过一个指针获取整个数组所有值的.所以正确的格式是int(*n_p)[3]=num;根据运算符先括号,所以是一个指向每个元素有三个数的数数组的,知道int,知道三个数,那么当n_p+1时加的就是12了,*(n_p+1)就能获取到num的第二个三元素数组的首地址.
对于二维数组来说使用指针获得数组中值的方法是-—num[n][m]=*((n_p+n)+m);
这样就可以使用指针表示变量和数组的值;
而且其是直接访问地址,在使用是直接传递一个地址值通过加减指针使用.