c语言指针初步剖析

1.c语言三大类型种类:
(1)内置类型:char, short, int, double等
(2)自定义类型:struct,union(c++中的class)等
(3)指针类型:int*, char*, float*等
不管是内置类型还是自定义类型都有相对应的指针类型
先来研究一下基本数据类型和基本类型的指针

2.基本数据和指针所占空间大小的问题
(1)如下代码在vc中的运行:
printf("%d\n",sizeof(char));
printf("%d\n",sizeof(short));
printf("%d\n",sizeof(int));
printf("%d\n",sizeof(float));
printf("%d\n",sizeof(double));    

32位环境windows下输出结果为:
1
2
4
4
8

(2)首先要明白32位环境的意义:
硬件为32bit(处理器是32位),操作系统是32bit,c编译器为32bit
所以不同环境下结果可能有差异,sizeof()判断的基本数据类型以下都按上述情况处理
(3)指针类型和基本类型之间的差异:
printf("%d\n",sizeof(char *));
printf("%d\n",sizeof(short *));                            
printf("%d\n",sizeof(int *));
printf("%d\n",sizeof(float *));
printf("%d\n",sizeof(double *));

输出结果为:
4
4
4
4
4
结果发现不管是什么指针类型,他们的sizeof求出的类型大小都是4,
初学者就会觉得很奇怪,让我们来看看什么原因:
一个指针本身也是一个变量,所以指针定义的数据我们称之为指针变量,指针变量也是有一个值的,这个值在内存中通常以16进制表示,例如0x0019ff3c,他是8个16进制表示,所以就是4个字节的大小,sizeof一个指针也就是4个字节的大小啦

3.对指针的进一步探究
(1)指针和变量之间关系
int a =10;
int b=20;
int *p=NULL;
int **s=NULL;
p=&a;
s=&p;

*p=100;
*s=&b;
这里定义了指针p和指向指针的指针s,让他们初始化都为NULL指针(这是一种出于安全的策略)。
而后p=&a表示了指针p指向了变量a,前提条件就是*p必须是int类型,所以他才能指向int类型的变量a。
s=&p表示了指针s指向了(指针)变量p,所以*s的类型就必须为int*类型,他才能指向int*类型的(指针)变量p

(2)指针的类型决定因素
从上述我们知道,指针能够指向一个变量,他们之间的类型必须要相同。
(3)指针的值问题
一个指针有和他相关的三个值:
p:p=&a之后指针p的值存放a的地址,对p的操作等于对a的地址操作,所以p改变了a也会被改变。
执行了p=&a的操作之后,p的值等于a的地址,例如0x0019ff2c,*p=a,他们的值为10
*p:*p=100相当是对p所指的变量(也就是a)进行再赋值,上面所说a也会被改变(p=&a),所以*p=a=100(之前是*p=a=10)。
&p:s=&p代表指针s存放了指针p的地址,同理s相当于对p的地址进行操作,*s的值也就是p的值(此时为a=10,**s=10)。
*s=&b,实质上也就是将指针p的指向b,这个时候等同于p=&b,也就是说改变了p的指向,这个时候**s=*p=b=20,a值不变,因为p已经不指向a了。
同理可得int ***q(指向一个指向指针的指针,三级指针)可以指向int **s,也就是q=&s,操作如上,此时s=&p,但是不管指针是几级指针,我们只能对指针变量(例如q)进行操作。

(4)指针的实质
指针的本质就是存放一个数据地址的变量,指针也必须有类型,指针的类型也就是所指变量的类型。
而一个变量的类型实质是规定该变量在内存中占的字节大小以及在内存中表示形式。这就决定了指针的类型的意义。
指针由于存放变量的地址,所以改变指针所指向的值,也就间接等同于改变该变量。
指针的值永远是一个内存地址,改变了指针的指向,也就是重新对指针的赋值,这个时候指针和原来指向的变量便没有关系了。
给定一个指针变量的值(内存值)和他的类型理论上能控制任意一片内存区域的数据(os允许的情况下)。

4.const和指针使用的细节
int a =10;
int b =20;

const int *p=&a;                // int const * p
*p = 20;                    // 错误
p = &a;                        // 正确
int * const p=&a;                // const在*的左边还是右边
const int * const p=&a;
*p=20;
p=&b;
printf("%d\n",*p);
(1)const int *p(int const *p)通常称作常量指针(指向常量的指针), *p的值为const,相当于*p的被封锁变为只读(readonly),
这个时候不能改变*p的值,但可以改变p的指向(p=&b)。但修改了a(p指向的对象)的值,*p会被改变,const只影响指针,不影响被指向的变量。
(2)int * const p称作指针常量(和指针变量对应),这个时候p本身为const,p被封锁为只读,不能改变指针p的值(这个地址值),
这时候可以改变*p的值来间接修改所指向变量的值,但不能改变p的指向。类似于将指针p和变量a的地址绑定了。
(3)const int * const p(const int const *p)通常叫做常量指针常量(指向常量的指针常量),兼顾以上两个属性。
既不能修改p的指针指向,又不能通过*p来改变所指对象的值。看似比较没有用。
在实际运用中,如果我们只需要这个变量的值,而不需要对其进行修改操作,这个能保护我们代码的安全性,以免误修改,参考函数的返回值。
(4)一般运用当中,我们应该根据所指向变量是否有const来确定指针是否需要有const

发布了1 篇原创文章 · 获赞 0 · 访问量 25

猜你喜欢

转载自blog.csdn.net/qq_37291326/article/details/105098132