c语言中 在学习指针时要知晓什么是指针,指针变量与普通变量的区别,基类型、指针变量的加减、指针变量的正确赋值等等,下面将一一介绍,
如果有错误,请联系我,我将做出修改
一般情况下,我们在程序中只需指出变量名,无需知道每个变量在内存中的具体地址,每个变量与具体地址的联系由C编译系统来完成。程序中我们对变量进行存取操作,实际上也就是对某个地址的内存单元进行操作,这种直接按变量的地址存取变量值的方式称为 ”直接存取“ 方式。
在C语言中,还定义了一种特殊的变量,这种变量只是用来存放内存地址的。我们定义一个普通的变量,然后得到这个存放这个变量的内存地址,再把这个内存地址编号存放到意外一个变量中,通过这个存放 "内存地址编号" 的变量来访问这个存放 "地址编号" 所指向的存储空降所存放的内容。这种方式称为 "间接存取" 方式。
简单说明:
1、普通变量中的内存空间存放的是,数值或字符等。 ----直接存取
2、指针变量中的内存空间存放的是,另外一个普通变量的地址。----间接存取
1. 指针类型的定义
类型名 *指针变量名1, *指针变量名2;
int *a, *p pd=10 ,ps =15;
在每个变量前的 ” * “ 是一个说明符(间接访问运算符),用来说明该变量是指针变量。注意在定义时,变量前的星号是不可省略的,忽略了也就变成了基本类型了,
2. 基类型
在定义指针变量时必须指定基类型。
不同类型的数据在内存中所占的字节数和存放方式是不同的(例如整型数据占4个字节,
字符型数据站1个字节)。如果想通过指针引用一个变量,只知道地址是不够的,因为无法判定是从地址为(如)2000的一个字节中取出一个字符数据,还是从2000和2001两个字节中取出short型数据,还是从2000到2003四个字节取出int或float型数据?必须知道该数据的类型,才能按存储单元的长度以及数据的存储形式正确的取出该数据。
指针变量的基类型用来指定此指针变量可以指向的变量的类型。
一个变量的指针的含义包括两个方面,一是以存储单元编号标识的地址(如编号为200的字节),一是它指向的存储单元的类型(如int ,char,float 等)。
在说明变量类型时,不能一般地说”a是一个指针变量“,而应完整的说:“a是指向整型数据的指针变量,b是指向单精度数据的指针变量,c是指向字符型数据的指针变量”。
3. 指针变量赋地址值
int *a, *p pd=10 ,ps =15;
p = &pd; //将pd的地址值赋值给指针变量p
p = &pd; //将pd的地址值赋值给指针变量p
p = &pd; //将pd的地址值赋值给指针变量pp = &pd; //将pd的地址值赋值给指针变量p
a = &ps;//将ps的地址值赋值给指针变量a
*a = *p; //指针P内存空间中的地址所指向的值赋值给a,也就是说将指针a指向的ps的值修改成10;
a = p;//指针p内存空间内容(地址)赋值给a,
” & ” 是求地址运算符 p = &pd 用来求出整形变量pd的地址赋给指针变量p 而使p指向pd。
上面定义的a和p是两个指向整形(int类型)变量的指针,也就是说变量a和p中只能存放int类型变量的地址。这时我们称int是指针变量a和p的基类型。
键盘的输入函数scanf(“格式控制符%d %c %s %lf %f”,&变量名,……);
scanf函数,输入的各变量之前都必须加符号&,这就是求地址运算。表示从终端读入的数据依次放入这些地址所代表的存储单元中,也就是说scanf函数要求输入项是地址值。因为当有语句 a=&ps ;(上面的)时,scanf("%d",a);和scanf("%d",&ps);是等价的。
printf函数是以整型输出指针变量的值,printf("%d",*a); 和 printf("%d",pd);即变量pd的值。
*p = 1;表示将整数1赋给p当前所指向的变量,如果p指向变量pd,则相当于把1赋给pd,即pd = 1;
下列代码将输出指针变量存放的数值。以及如何给指针变量赋值及输出。
#include
int main(){
int *a,*p,pd=10,ps=5;
p = &pd;
a = &ps;
printf("指针变量p的地址值为:%p \t 指针变量a的地址值为:%p\n\n",&p,&a);
printf("pd的地址为:%p \t ps的地址为:%p\n\n",&pd,&ps);
printf("指针变量p内存空间中的的地址为:%p \t 变量指针a内存空间中的的地址为:%p\n\n",p,a);
printf("指针变量p的值为:%d \t 指针变量a的值为:%d\n\n",*p,*a);
printf("---------------------------------\n\n\n");
a = p;
printf("将p内存空间中的地址赋值给a之后\n\n");
printf("指针变量p内存空间中的的地址为:%p \t 变量指针a内存空间中的的地址为:%p\n\n",p,a);
printf("指针变量p的值为:%d \t 指针变量a的值为:%d\n\n",*p,*a);
return 0;
}
这是上面程序的输出形式
指针变量p的地址值为:000000000062FE40 指针变量a的地址值为:000000000062FE48
pd的地址为:000000000062FE3C ps的地址为:000000000062FE38
指针变量p内存空间中的的地址为:000000000062FE3C 变量指针a内存空间中的的地址为:000000000062FE38
指针变量p的值为:10 指针变量a的值为:5
---------------------------------
将p内存空间中的地址赋值给a之后
指针变量p内存空间中的的地址为:000000000062FE3C 变量指针a内存空间中的的地址为:000000000062FE3C
指针变量p的值为:10 指针变量a的值为:10
4. 移动指针
所谓移动指针就是对指针变量加上或减去一个整数,或通过赋值运算,
是指针变量指向相邻的存储单元。只有当指针指向一串连续的存储单元时,指针的移动才有意义。
在看这个之前,请先自己回忆数组,一维数组,二维数组,字符串,
指针指向数组元素时,
加一个整数(用 + 或 +=),如 p+1;
建一个整数(用 - 或 -=),如p-1;
自加运算,如 ++p,p++;
自减运算,如 --p,p--;
两个指针相减,如p1-p2(只有p1 和 p2 都指向同一数组中的元素时才有意义)。
如果指针变量p已指向数组中的一个元素,则 p+1 指向同一数组中的下一个元素,p-1 指向同一数组中的上一个元素。
注意的是:执行 p+1 时并不是将 p 的值(地址)简单地加1,而是加上一个数组元素所占用的字节数。