指针的应用

来源:互联网 发布:高仿耐克鞋淘宝店 编辑:程序博客网 时间:2024/06/06 01:44

指针对于C语言来说是非常重要的一环,可以说如果不会使用指针就说明没有真正掌握C语言。现在进一步总结指针,希望对其有更深层次的理解。

★别名陷阱

●什么是别名?

int temp = 3;int *p,*q;p = &temp;q = &temp; 
对于一块内存来说,有多个指针同时指向这块内存,这多个指针中的每一个指针都是其他指针的别名。想上面这段代码,其中p是q的别名;同样q也是p的别名。

●别名陷阱

对于指针来讲,对指针操作就会直接操作指针指向的内存的内容。例如上面代码,如果对p指向的内存进行赋值*p = 5;那么该内存的值就会变成5,这样一来q指向的内存中的数值也会发生变化,内存中的值由3变成5。尤其在优化程序的时候,会造成一些比较隐蔽的错误,因此要十分的小心。

#include <stdio.h>#define a *p#define b *qint main(void){    int x;    int *p,*q;        p = &x;    q = &x;    a = 2;    b = 3;    printf("%d",a + b);    return 0;} 
像上面这个程序a+b的值为6,就是因为b=3;这条语句修改了变量x存储的内容,而p和q都同时指向x,使*p = 3,最后使得a+b=6

★数组指针

C语言中,一个指针变量可以指向一个数组,这样的指针叫做数组指针。例如:

int (*p)[5];表示p是一个指针,指向一个数组对象,该数组是一个拥有5个整形元素的数组。因此,p+1时p移动的字节数应该等于p所指向的数组对象的字节数。像上面这个指针应当移动sizeof(int)*5。

个字节。

#include<stdio.h>int main(void){    int a[5] = {1,2,3,4,5};    int (*p)[5];    int *ptr;        p = &a;    ptr = (int *)(p + 1);    printf("%d",*(ptr - 1));    return 0;    } 
输出的结果是:5。分析一下原因,p是数组指针,则p+1指向的是a[5]。那么*(ptr-1)为什么是4呢?是因为ptr并非是数组指针而是整形指针。ptr = (int *)(p +1)就是将数组指针转换成整形指针。

区别:数组指针和指针数组

数组指针是一个指针,它指向数组;指针数组是一个数组,只不过数组中的每个元素都是指针。

★指针的指针

C语言中,指针可以指向指针,成为指针的指针。

int **p;表示定义一个指针变量,它指向的是另一个指针变量,这个指针变量又指向一个整形变量。  

#include <stdio.h>int main(void){    int a;    int *p;    int **q;        a = 100;    p = &a;    q = &p;        printf("%d\n",a);    printf("0x%x\n",*p);    printf("0x%x\n",*q);    //system("pause");    return 0;    }


★指针类型的意义

指针的本质是一个无符号的整数,代表一个内存单元的单元号。但是在定义一个指针变量的同时,往往会声明该指针变量所指向的数据类型:int *p,表示该指针变量p指向的是一个整形。其作用是告知编译器需要从该地址处向后看多少个字节,把这些字节当做一个对象来看待。

★void*型指针

void*指针表示一个任意类型的指针,其可以指向任意一个类型的内存单元。

指针类型的意义在于使编译器可以知道从该指针所表示的地址开始,向后把多少个字节看成一个整体。任意类型的指针不能告诉编译器该向后看多少个字节,那么也就无法引用任意类型指针所指向的数据,void*类型似乎没有什么意义。但如果编译器不知道用户要把指针指向的内容作什么用途的时候,void*指针就起到作用了。编译器认为一块内存用户做什么都是合法的,那么这块内存的指针就是任意类型的。

有一个例子是:malloc函数分配一块内存后,得到这块内存的首地址,返回的就是void*类型的指针。

指针的本质是一个无符号的整数,从理论上将指针和一个整数的比较应该是没有问题的,但是C语言编译器同样不允许两者进行比较。因此在比较一个指针和一个整形数据时,首先要做的就是将整形数据转换为该指针类型,之后再进行比较。



2 0