C语言指针基础

来源:互联网 发布:pensen是什么软件 编辑:程序博客网 时间:2024/05/22 09:49
指针是C语言的特色,也被认为是一把双刃剑,利用好的话程序执行效率高,利用不好的话则出大错。
下面以整型为例,总结各种指针变量的声明语法和相关注意事项。
 
总的来说,在理解指针时,个人认为把握“指针变量的值是一个数据在内存中的地址”这一点是关键。这样以来,我们就理解了在对指针变量进行初始化时,需要将一个地址赋给指针变量。那我们平常所接触到的地址有哪些呢?首先使用“&”可以取一个变量的地址。另外,数组变量的名就是一个地址(如一维数组变量名是数组元素在内存中存放的首地址,如int a[] = {1,2,3};那么a的值就是一个地址。而a[0]、a[1]、a[2]才是数据1,2,3 )。特别注意的是,字符串在内存中是以字符数组的形式存放的,因而可以将一个字符串赋给一个字符型指针变量。
 
下面以整型指针变量为例,介绍相关知识点。
①int  *p; 指向整型量的指针------指向变量的指针,这个最常用
 
上边是指针变量的声明,而一般在声明的时候也可以顺便初始化,形如“int p =  8; int *point_p = &p;”
不要被这种形式所迷惑,其实就相当于先声明,然后对指针变量进行赋值,即“int p = 8, *point_p;  point_p = &p;”。星号在其中只是标识了变量是指针变量。
 
星号的另外一个用处是通过指向一个内存地址而取到该地址存放的数据。指针变量的值是一个内存地址,*point_p表示指该内存地址,这样也就可以访问到该地址存放的数据了。
                      
②int  *p[ ];指针数组,每个元素都是一个指针变量。
指针数组相当于把指针变量进行了批量声明,这些指针变量的值都是一个地址,而用于存放这些指针变量的内存是连续的,因为它们在同一个数组里。
这个很经典的用处是使用一组字符串对字符型指针数组进行初始化,在访问字符串时用字符型指针变量。
 
#include <stdio.h>void main(){ char  *p[7]={"Sun.","Mon.", "Tue.",            "Wed.","Thur.","Fri.","Sat."};   int code;   scanf("%d",&code);   printf("Today is %s",p[code]);}
                        
③int  (*p)[ ]; 指向一维整型数组的指针
可以使用偏移量法和指针移动法对一维数组中的元素进行访问。两者的区别在于,前者并不改变指针变量的值,而后者则改变了指针变量的值。
假如当前p值为一维整型数组的首地址,则*(p+1)和*p++均可以表示索引为1处的元素值。
 
④int  *p( );返回指针值的函数
可以理解为返回的是地址,在另一个函数中调用它时,会把这个返回的地址赋给一个相同类型的指针变量。
 
main(){static float score[][4]={{86,90,80,92},                                         {96,88,96,86},{84,94,85,74}};float *search(), *p;  int i,m;  //m是要查找学生的学号scanf("%d",&m);p=search(score,m); //score为指向行的指针for(i=0;i<4;i++)   printf("%5.2f\n",*(p+i));}float *search(pointer,n)    float (*pointer)[4]; //指向包含4个元素的一维数组的指针int n;{ float *pt;  pt=*(pointer+n);     /* 指向score数组第n行 */  return(pt);}
例子摘自清华大学黄维通老师ppt

 

在main函数调用函数search,返回的就是一个指针,也可以理解是一个地址值。


⑤int  (*p)( ); 指向函数的指针

在初始化时,直接将一个声明过的函数名赋给它
在使用时,将需要的参数赋给它即可。
#include "stdio.h"call(int x,int y,int (*func)(int , int)){  return( (*func)(x,y));   } add(int x,int y) {    return (x+y);  }main(){int *oper(int,int), x=10,y=5;  oper = add; printf("%d+%d=%d\n",x,             y,call(x,y,oper));}

⑥int **p;  二级指针。
我们常用的是指针是一级指针,它的值是一个地址,现在,如果它本身的地址又用一个指针变量来存储,那么这里的指针变量就是二级指针了。

相当于一个指针链,根据二级指针变量的值,我们在内存中找到了一级指针变量,再根据一级指针变量的指,我们在内存中找到了梦寐以求的数据。

⑦动态指针
指针变量并不是一经初始化其值就不能改变,而是可以对其重新赋值的。这表现出来的就是动态指针。
 
一般指针在使用前要赋值,使用后要释放,可以这样:void free(void * ptr)——释放由指针指向的空间
使用stdlib库中的以下三个函数(其实它们都是前边提到过的返回指针值的函数)可以返回特定大小空间的地址,赋给指针变量。
void *malloc(size_t size)——为一个对象分配指定大小的空间
void * calloc(size_t nmemb, size_t size)——为nmemb个对象分配指定大小的空间
void * realloc(void * ptr, size_t size)——释放指针指向的老空间,使其指向新空间,并将老空间数据搬到新空间