指针

16 篇文章 0 订阅

  1)为什么要使用指针?
     a、指针的基本概念:
        在计算机中,所有的数据都是存放在存储器中的。一般把存储器中的一个字节称为一个内存单元,不同的数据类型所占用的内存单元数不同,如整型变量占4个单元,字符量占1个单元等,为了正确地访问这些内存单元,必须为每个内存单元编号。根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址。既然根据内存单元的编号或地址就可以找到所需的内存单元,所以通常也把这个地址称为指针。
        注:内存单元的指针和内存单元的内容是两个不同的概念。
        总结:对于一个内存单元来说,单元的地址即为指针,其中存放的数据才是该单元的内容。
b、指针式C语言中最重要的内容之一:"无指针,不自由"
   指针部分的学习也是难点之一,如果深入的学习指针,可以参考《指针的艺术》


  2)使用指针的好处
     a、为函数提供修改调用变量的灵活手段
b、让函数有多个返回值
c、可以改善某些子程序的效率
>>在数据传递时,如果数据块较大(比如说数据缓冲区域或比较大的结构),这时就可以使用指针传递地址而不是实际数据,即提高传输速度,又节省大量内存。
d、为动态数据结构(如二叉树、链表)提供支持。
 
  3)变量的存取方式  
a、存取方式分为两种:直接存取和间接存取
    ①直接存取:变量的赋值和取值(通过变量名进行存取值)
         ②间接存取:通过指针(地址)间接操作完成。


  4)指针变量概念及定义方法
     a、指针变量
         在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。因此,一个指针变量的值就是某个内存单元的地址或称为某内存单元的指针。  


注意:
    ①严格意义上来说:指针是一个地址,是一个常量。
②指针变量是存放一个地址,是一个变量。
 
  5)定义一个指针变量
     a、对指针变量的定义包括三个内容:
        ①指针类型说明:即定义变量为一个指针变量。
②指针变量名
③变量值(指针)
一般形式为:类型说明符 *变量名
说明:其中,*表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数据类型。
例如:
   int *pi; //一个指向整型变量的指针
long *pi; //一个指向长整型变量的指针
float *pf; //一个指向浮点型变量的指针
char *pc; //一个指向字符型变量的指针。
        注意:
  ①在定义指针时,"*"表示定义的变量是指针变量,变量的值只能存放地址。
  ②一个类型的指针只能指向同类型的变量,不能指向其它类型的变量。
③指针也可以被声明为全局、静态局部和局部的。


  6)指针变量的初始化方法
      a、设有指向整型变量的指针变量P,如要把整型变量a的地址赋予P可以有以下两种方式:
     ①指针变量初始化的方法一:定义的同时进行初始化
     例如:int a=5;
 int *p=&a;
 a)完全初始化
     int *p=&a;//用a的地址初始化 p这个指针变量
           //另一种描述方法:p指向了a
 int *p=&a,p2=&a;  //p1  p2都指向了a
 b)部分初始化
     int *p3=&b,*p4;//定义了两个指针变量 p3  p4
 p4=&b;
 ②指针变量初始化的方法二:先定义后初始化
     int *p7;
 p7=NULL;//这种方法最好不使用,可能会出现问题
 
 ③如果定义了一个指针变量,但不知道这个指针变量指向谁
     int *p8=NULL;//NULL  是空(0)
 int *p9=0;   //空
 把一个指针赋值为空则这个指针变量什么也不指向
  常见易范的错误:int *p=1000;//这种方法是错误的,但是不会报错,有不同的警告。但是杜绝这种写法
 
 b、指针变量的使用:定义指针变量-->初始化指针变量-->使用指针变量(使用指针变量间接的存取内存单元的值)


 c、指针变量如果不初始化会有什么后果?
       如果一个指针变量定义以后,如果不进行初始化,这个指针变量存放的是一个垃圾数,这个指针变量被称为野指针
 d、指针变量如何进行初始化?指针变量应该用地址初始化。
 
 注意:①多个指针变量可以指向同一个地址
       例如:
int a=5;
int *p=&a;
int *p1=&a;
int *p2=p1;
            ②指针的指向是可以改变的
③指针没有初始化,里面是一个垃圾值,这时候我们称这是一个野指针。
   如果操作一个野指针:
   a)可能会导致程序崩溃
b)访问你不该访问的数据
所以指针必须初始化才可以访问其所指向的存储区域。


  7)使用"*"获取指针对应存储区域的内容
        指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予具体的值。未经赋值的指针变量不能使用,否则将造成系统混乱,甚至死机。指针变量的赋值只能赋予地址,决不能赋予任何其他数据,否则将引起错误。在C语言中,变量的地址是由编译系统分配的,对用户完全透明,用户不知道变量的具体地址。
       例如:
      int a=10;
      int *p=&a;
  int value=*p;//获取指针变量指向的内存单元的内容
  printf("%d\n",value);//输出为4
         两个有关的运算符:
①&    取地址运算符
②*    指针运算符(或称”间接访问“运算符)
C语言中提供了抵制运算符&来表示变量的地址。其一般形式为:
  &变量名:
  *指针变量名    //获取指针变量指向的内存空间
  如:&a便是变量a的地址,&b表示变量b的地址。变量本身必须预先说明。
  
  8)关于*的使用注意:
        ①在定义变量的时候 * 是一个类型说明符,说明定义的这个变量是一个指针变量
②在不是定义变量的时候 * 是一个操作符,访问指针所指向存储空间。


  9)应用:用函数实现两变量值交换
         注意:!!!!!!!!!!!!!!代码:
void swap2(int *p1,int *p2){
int *temp;
temp=p1;
p1=p2;
p2=temp;
}//值不会改变,方法执行后内存销毁,值不会交换
void swap1(int a,int b){
int temp;
temp=a;
a=b;
b=temp;
}//值不会改变,方法执行后内存销毁,值不会交换
void swap3(int *p1,int *p2){
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}//此种方法值可以交换
 
void main(){
int a=5,b=3;
swap1(a,b);
printf("a=%d,b=%d",a,b);//输出为a=5,b=3
swap2(&a,&b);
printf("a=%d,b=%d",a,b);//输出为a=5,b=3
swap3(&a,&b);
printf("a=%d,b=%d",a,b);//输出为a=3,b=5
}


  10)指针常见的应用场景
       a、在函数中间接访问调用者中的变量
      例如:
  void changeValue(int *p){
*p=100;
  }
  void main(){
int a=1;
int *p1=&a;//p1指向了a
printf("%d\n",*p1); //输出1
printf("%d",a);//输出1
changeValue(p1);
  }
  b、函数返回多个值
   用指针让函数可以有多个返回值:
用指针让一个函数实现加减乘除
void caculator(int x,int y,int *add,int *jian,int *cheng,in *chu){
*add=x+y;
*jian=x-y;
*cheng=x*y;
*chu=x/(float)y;
}
void main(){
int add=0;
int jian=0;
int cheng=0;
float chu=0.0f;
caculator(12,4,&add,&jian,&cheng,&chu);
printf("add=%d\n",add);
printf("jian=%d\n",jian);
printf("cheng=%d\n",cheng);
printf("chu=%d\n",chu);
}


  11)二级指针介绍
      a、二级指针介绍
     如果一个指针变量存放的又是另外一个指针变量的地址,则称这个指针变量为指针的指针变量。也称为"二级指针"。
          通过指针访问变量称为间接访问。由于指针变量直接指向变量,所以成为"一级指针"。而如果通过指向指针的指针变量来访问变量则构成"二级指针"
 例如:
     int a=5;
 int *p=&a;
 int **p1=&p;
 //*p1-->存储的是int型变量a的地址
 //**p1-->存储的是*p1地址指向的值,即5
  12)指针为什么要区分类型
      在同一个编译器环境下,一个指针变量所占用的内存空间是固定的。 
      如:
   int *p1;
char *p2;
double *p3;
float *p4;
void *p5;
printf("sizeof(p1) int     --->%ld\n",sizeof(p1));//输出结果为:sizeof(p1) int     --->8
printf("sizeof(p2) char    --->%ld\n",sizeof(p2));//输出结果为:sizeof(p1) char    --->8
printf("sizeof(p3) double  --->%ld\n",sizeof(p3));//输出结果为:sizeof(p1) double  --->8
printf("sizeof(p4) float   --->%ld\n",sizeof(p4));//输出结果为:sizeof(p1) float   --->8
printf("sizeof(p5) void    --->%ld\n",sizeof(p5));//输出结果为:sizeof(p1) void    --->8
           
        结论:定义什么类型的指针就应该指向什么类型的变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值