目录
1.指针是什么
2.与指针有关的运算符
3.指针的初始化
4.基本类型指针
5.指针和数组
6.多级指针
7.指针变量的运算
1.指针是什么
从根本上看,指针(pointer)是一个值为内存地址的变量(或数据对象)。比如char类型变量的值为字符,int 类型变量的值是整数,指针变量的值是地址。例如:
int * p;//定义了一个指针变量p,p的类型为int *,p指向的地址为 int 类型
2.与指针有关的运算符通俗来讲,指针就是地址,地址就是指针,不过要注意的是,虽然我们在平时会将指针变量简称为指针,但指针变量和指针是有所不同的,指针变量是存放地址的变量,也就是存放指针的变量。
1) * (星号)
C语言中*可以表示乘号,也可以表示指针符号。这两个用法是毫无关联的,只是恰好用了同一个符号而已,星号在用于指针时有两种用法:
①指针定义时,*结合前面的类型用于表明要定义的指针的类型;
②指针解引用,解引用时*p表示p指向的变量本身。
int *p;//这是星号的第一种用法,定义了一个指针变量 P int *q ,*r;//当同时想定义两个或者多个指针时,也可以采用这样的语句 int i=5,j; p = &i; //p保存了i的地址,p指向i j = *p;//这是星号的第二种用法,把p指向的地址上的值赋给j,此时j=5
2) & (取地址符)
取地址符使用时直接加在一个变量的前面,然后取地址符和变量加起来构成一个新的符号,这个符号表示这个变量的地址。
3.指针的初始化指针初始化目的就是让指针知道指向那个地址。共有两种方式初始化指针:①在声明指针时便告诉指针指向地址;②不在声明指针的时候初始化,而是把地址直接赋值给指针变量。
注意:不可以在指针不清楚指向地址的情况下给指针赋值(但是char p=0或者p=NULL除外,该语句表示指针为空)。
①在声明指针时便告诉指针指向地址
#includeint main (void) { int i=5; int *p=&i; return 0; }
②不在声明指针的时候初始化,而是把地址直接赋值给指针变量
#includeint main (void) { int i=5; int *p; p = &i; return 0; }
③不可以在指针不清楚指向地址的情况下给指针赋值(错误)
#include4.基本类型指针int main (void) { int i=5; int *p; *p = 5; return 0; }
int * p; int i=5,j; p = &i;//一个指针变量指向某个普通变量,则*指针变量等同于普通变量 //对于此处即:*p=i=5 在所有出现 *p 或 i 的位置,两者可相互替换 j = *p;//通过这几步,就可以将 i 的值 5 赋给 j
1)内存泄漏
指针指向一个地址,也就是一个空间,如果只给指针分配空间,而未释放掉分配的空间,就会导致内存泄漏,导致内存越用越少;但如果,有多个指针同时指向同一个空间,而进行多次内存释放,就会使程序崩溃,导致无法运行。
2)空指针NULL
空指针就是值为0的内存逻辑地址,当对逻辑地址0(NULL)所代表的内存进行读写 *** 作时,程序就会崩溃。(返回值为指针的函数通常使用空指针作为失败时的返回值)
3)野指针
指向的位置不可知的指针。
出现原因:①声明指针后并未初始化
②变量内存释放后,指针变量还保存着该变量的内存地址
5.指针和数组一维数组名,是一个指针常量,他存放的是数组第一个元素的地址,例如:
#includeint main (void) { int a[5]; printf ("%dn",&a[0]);//此处输出为a[0]的地址 printf ("%dn",a);//此处输出为数组名a的含义 return 0; }
若两者输出结果相同,则说明一维数组名存放的是数组第一个元素的地址,运行程序输出结果如下:
显然,两者输出结果相同,那么说明一维数组名存放的是数组第一个元素的地址。
指针和下标总存在着这样一个关系:如果 p 是一个指针变量,则 p[i] 永远等价于 *(p+i)
# includeint main(void) { int a[5] = { 1,2,3,4,5}; int i; for( i = 0 ; i < 5 ; i++ ) { printf("%d " , a[i]); } printf ("n"); for(i = 0 ; i < 5 ; i++ ) { printf("%d " , *(a+i)); } return 0 ; }
运行程序,输出结果如下:
由此便可以证明该关系,p[i] 等价于 *(p+i)
注意区分:
int (*p[10])的含义是定义了一个数组,数组名为p,其中包含10个指针,指针指向整型类型数据
int (*p)[10]的含义是定义了一个指针,指针指向一个数组,数组中有10个元素,元素类型为整型
6.多级指针如果一个指针指向的是另一个指针,我们就成他为二级指针,或者指向指针的指针。
那么如果指针指向的是一个二级指针,我们就称他为三级指针.......
那么对于多级指针,我们又该如何 *** 作呢?
#includeint main (void) { int i=10; int *p = &i;//定义了一个一级指针, p 存放 i 的地址 int **q = &p;//定义了一个二级指针,q 存放 p 的地址 int ***r = &q;//定义了一个三级指针,r 存放 q 的地址 r是int ***类型,所以r只能存放int **类型变量的地址 //r = &p;//这样写是错误的 r是int ***类型,所以r只能存放int **类型变量的地址 不能存放int *类型变量的地址 printf ("%dn",i); printf ("%dn",*p); printf ("%dn",**q); printf ("%dn",***r); return 0; }
i p q r 之间的关系可通过下图来理解
7.指针变量的运算指针变量不能相加 不能相乘 不能相除
如果两个指针变量指向同一块连续空间中不同的储存单元,则这两个指针变量可以相减。
int i=5; int j=10; int *p = &i; int *q = &j;
此时 p-q 并没有实际意义,若将 p 和 q 放入同一个数组中,p-q 才会有实际意义。
#includeint main (void) { int a[5]; int *p, *q; p = &a[1]; q = &a[4]; printf ("p和q所指向的单元相隔%d个单元n",q-p); return 0; }
运行结果如下:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)