c语言的指针一些代码和解析,C语言篇:指针

注意:本篇不适合做入门教学,建议有一定基础的爱好者做深度学习。

指针是C语言的灵魂。并不是所有的高级语言都具有指针,C++虽然有指针,但是从设计上希望程序员尽可能少得使用指针,C则不然。C是追求效率的,所以有时不得不把安全问题交给程序员。正是指针赋予了C“直接操作内存”的能力,也正是指针使一些复杂的数据结构成为可能。

流畅且准确地使用指针,是掌握C语言精髓的关键。

什么是指针

在程序运行的过程中,所有的数据都是放在主存(内存)里的,主存按字节编址,每个字节对应一个编号,称为地址,计算机通过地址可以精确地存取数据。

在C语言中有一类数据类型,它保存主存地址,并可以通过运算符对该地址的数据进行操作。如果它保存的是某个变量的地址,可以形象地说它指向了某个变量,所以这类数据类型称为指针。

指针的存储方式

主存从0开始顺序编址,所以指针的值是非负整数,实际上,指针的存储结构与unsigned long相同,在32位机上指针是32位,而在64位机上指针是64位。

指针类型

前面已经提到,指针是一类数据类型,这是一个大家族,拥有非常多的指针类型,尤其是当指针与数组结合以后,其类型描述会变得非常复杂。

也许会有疑问,既然存储方式已经确定,为什么还需要众多的指针类型?

其实,指针类型描述的不是自身数据的类型,而是其指向数据的类型。想象一下,一个int变量一般是4个字节,而指针储存的是1个字节的地址,怎样才能让指针指向这个变量。C的做法是,储存这个int变量的第一个字节的地址,即首地址。之后,我们根据指针存储的数据找到了该地址,这是1个字节的地址,该怎么表示这里有一个4字节的int变量。同样,我们把这个地址作为首地址,把这个字节和其后的3个字节一起作为一个int变量。显然,我们需要明确表示,这个指针指向一个int变量,否则无法使用指针进行任何操作。这就引出了指针类型。

同时,指针之间可以进行有限的运算,且指向不同类型数据的指针运算规则是不同的,这是指针类型的另一个用途。

& 和 * 运算符

& 运算符:又称为“取址运算符”,顾名思义,其作用是得到一个变量的地址。严格来说,它取的是变量的首地址,并且包含了变量类型信息,所以,它返回的是一个指针(请勿把指针和指针变量弄混),并且它是一个右值。& 运算符为一元运算符,右结合,优先级大于算术运算符,运算对象必须是变量(暂不引入引用的概念,并姑且把主存中的固定数据都称为变量),而不能是例如a + 1这样的表达式。

* 运算符:取值运算符,也称“解引用运算符”,返回指针所指的变量。* 运算符返回左值,如果a指向b,那么*a和b是相同的,完全可以混用。* 运算符也是一元运算符,右结合,优先级与 & 运算符相同。* 运算符的运算对象可以是任何指针类型(除了void *)的值,而不一定是指针变量。

指针变量的声明

C变量声明的设计理念是:声明方式应该与使用方式相同。

首先,我们需要指定指针所指变量的类型,以int为例。当我们使用指针时,需要在指针变量前使用 * 运算符,所以在声明时也应在变量名前加 * 。所以,声明一个指向int变量的指针应写为:

int *var;

复制代码

若要声明一个“指向‘指向char变量的指针’的指针”,因为我们需要两次使用 * 运算符才能得到这个char变量,所以声明时也要写两个 * ,写为:

char **var;

复制代码

值得一提的是,以下三种写法都是合法的:

int *var;

复制代码

int* var;

复制代码

int * var;

复制代码

声明中 * 只对与它相邻的那个变量有效,也就是说,如果有以下声明:

int* a, b;

复制代码

则声明了一个指针变量a和一个int变量b,如果想同时声明两个相同类型的指针,需要在每个变量名前加 * ,所以建议采用第一种写法。如下:

int *a, *b;

复制代码

指针运算

指针运算赋予了指针更灵活的用法,在数组等操作中尤为明显。

指针运算旨在使指针偏移到相邻的对象,或指向一个确定的位置,也可以求出两个指针所指对象在主存中的距离。

赋值运算

将一个指针类型的值赋值给一个指针变量,最基本的用法如下:

int var = 0;

int *pt;

pt = &var;

复制代码

一般情况下,赋值号两边的指针类型必须相同。

int var = 0;

int *pt1;

pt1 = &var; // Correct

int *pt2;

pt2 = pt1; // Co

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值