C 语言 指针的详解

1、指针的基本概念


    指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型、指针所指向的类型、指针的值或者叫指针所指向的内存区、指针本身所占据的内存区。 



1.指针的类型


     从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。 这是指针本身所具有的类型。


(1)int*ptr;//指针的类型是 int*
(2)char*ptr;//指针的类型是 char*


2.指针所指向的类型


     当你通过指针来访问指针所指向的内存区时, 指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。 

(1)int*ptr; //指针所指向的类型是 int
(2)char*ptr; //指针所指向的的类型是 char



3.指针的值----或者叫指针所指向的内存区或地址


   指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在 32 位程序里, 所有类型的指针的值都是一个 32 位整数,因为 32 位程序里内存地址全都是 32 位长。指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为 si zeof(指针所指向的类型)的一片内存区。 以后, 我们说一个指针的值是 XX,就相当于说该指针指向了以 XX 为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。


    指针所指向的内存区和指针所指向的类型是两个完全不同的概念。指针所指向的类型已经有了, 但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。


4 指针本身所占据的内存区


    指针本身占了多大的内存? 你只要用函数 sizeof(指针的类型)测一下就知道了。在 32 位平台里,指针本身占据了 4 个字节的长度。指针本身占据的内存这个概念在判断一个指针表达式(后面会解释) 是否是左值时很有用。


2、 指针的算术运算


    指针可以加上或减去一个整数。 指针的这种运算的意义和通常的数值的加减运算的意义是不一样的,以单元为单位。 



3、 运算符&和*


     这里&是取地址运算符,*是间接运算符。&a 的运算结果是一个指针,指针的类型是 a 的类型加个*,指针所指向的类型是 a 的类型,指针所指向的地址嘛,那就是 a 的地址。*p 的运算结果就五花八门了。总之*p 的结果是 p 所指向的东西,这个东西有这些特点:它的类型是 p 指向的类型,它所占用的地址是 p所指向的地址。





4、 指针表达式


     一个表达式的结果如果是一个指针, 那么这个表达式就叫指针表式。指针表达式也具有指针所具有的四个要素: 指针的类型,指针所指向的类型,指针指向的内存区,指针自身占据的内存

int a,b;
int array[10];
int *pa;
pa=&a; //&a 是一个指针表达式。
Int **ptr=&pa; //&pa 也是一个指针表达式。
*ptr=&b; //*ptr 和&b 都是指针表达式。
pa=array;
pa++; //这也是指针表达式。



5、 数组和指针的关系


intarray[10]={0,1,2,3,4,5,6,7,8,9},value;
value=array[0]; //也可写成: value=*array;
value=array[3]; //也可写成: value=*(array+3);
value=array[4]; //也可写成: value=*(array+4);


     上例中, 一般而言数组名 array 代表数组本身,类型是 int[10],但如果把 array 看做指针的话,它指向数组的第 0 个单元,类型是 int* ,所指向的类型是数组单元的类型即 int。


6、 指针和结构类型的关系


可以声明一个指向结构类型对象的指针。


struct MyStruct
{
int a;
int b;
int c;
};


struct MyStruct ss={20,30,40};
//声明了结构对象 ss, 并把 ss 的成员初始化为 20, 30 和 40。
struct MyStruct *ptr=&ss;
//声明了一个指向结构对象 ss 的指针。 它的类型是
//MyStruct *,它指向的类型是 MyStruct。
int *pstr=(int*)&ss;
//声明了一个指向结构对象 ss 的指针。 但是 pstr 和
//它被指向的类型 ptr 是不同的。



7、 指针和函数的关系


   可以把指针作为函数的形参。 在函数调用语句中, 可以用指针表达式来作为实参。



8、 指针类型转换


    如果有一个指针 p, 我们需要把它的类型和所指向的类型改为TYEP *TYPE, 那么语法格式是: (TYPE *)p;这样强制类型转换的结果是一个新指针,该新指针的类型是TYPE *。它指向的类型是 TYPE,它指向的地址就是原指针指向的地址。


    而原来的指针 p 的一切属性都没有被修改。(切记)一个函数如果使用了指针作为形参, 那么在函数调用语句的实参和形参的结合过程中,必须保证类型一致 ,否则需要强制转换。



总结:


    考试干货拿去。最开始学指针是当初考C++的时候,当时理解不很深入。第二次的学习,就有种熟悉的感觉了。学习就是这样重复,才有力量。


评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值