学习笔记之 指针

本文是学习linux c编程一站式学习的学习笔记

一,指针与数组

对于


1 ,指针之间是可以相互比较,同时指针之间也可以做减法运算,不过是有条件的。指针之间比较的是地址,只有只想同一个数组中元素的指针之间相互比较才有意思。指针之间相减表示两个指针之间相差的元素个数,同样只有指向同一个数组元素的指针之间相减才有意义。

2 ,数组名与指针的区别

在取数元素时用数组名和用指针的语法一样,但,如果把数组名作为左值使用,和指针就用区别了。如:pa++ 合法,而 a++ 非法。数组名做右值时转换成指向首元素的指针,但做左值仍然表示整个数组的存储空间,而不是首元素的存储空间,但支持取地址运算符 & ,所以 &a 是合法的。


const 限定符

const 限定符和指针结合在一起经常出现在很多公司的面试题中。

1 const int *a int const *a

这两种表示的意思相同。a 是一个指向 const int 型的指针, a 所指向的内存单元不可改写,所以 (*a)++ 是不允许的,但 a 可以改写,所以 a++ 是允许的。

2 int * const a

a 是一个指向 int 型的 const 指针, *a 是可以改写的,但 a 不允许改写。

3,const int * const a

a 是一个指向 const int 型的 const 指针,因此 *a a 都不允许改写。

可以通过下面的方法来记忆:

* 读成指向,先读 * 前面的,后读 * 后面的内容,最后加上指针两字。

如: int *const a ;读成: a 是指向 int 型的 const 指针。

const 规则两条:

1 ,指向非 const 变量的指针或非 const 变量的地址可以传给 const 变量的指针。编译器做隐式转换。

2 ,指向 const 变量的指针或 const 变量的地址不可以传给指向非 const 变量的指针。下面的代码将出错。

,指向指针的指针与指针数组

 

1,指向指针的指针

 

 

这样定义之后,表达式*ppi pi 的值,表达式 **ppi i 的值,即 0 i pi ppi 这三个变量之间的关系如下图所示。

  

2,指针数组

 如:int *a[10];表示int型指针数组,一共有10个元素,每个元素都是int*.

 

3,指针数组同指向数组的指针  

下面定义一个指向数组的指针,该数组有10 int 元素

Int (*a)[10];

同指针数组的定义int *a[10]; 相比,仅仅多了一个() 括号。我们可以认为 [] * 有更高的优先级,如果 a 先和* 结合则表示 a 是一个指针,如果 a先和 [] 结合则表示 a 是一个数组。int *a[10]; 这个定义可以拆成两句:

tydef int * t;

t a[10] ;代表 int* a 则是由这种类型的元素组成的数组

int (*a)[10] ;可以拆分成:

typedef int t[10] ;  

t * a ;

t代表 10 int 组成的数据类型。 a 则是指向这种类型的指针。

 

指向数组的指针的使用:

Int a[10] ;

Int (*pa)[10]=&a ;

注意,&a[0] 表示数组a 的首元素的首地址,而&a 表示数组a 的首地址,显然这两个地址的数值相同,但这两个表达式的类型是两种不同的指针类型,前者的类型是int * ,而后者的类型是int (*)[10] *pa 就表示pa 所指向的数组a ,所以取数组的a[0] 元素可以用表达式(*pa)[0] 。注意到*pa 可以写成pa[0] ,所以(*pa)[0] 这个表达式也可以改写成pa[0][0] pa 就像一个二维数组的名字。下面的例子:

 
pa[0]a[0]取的是同一个元素,唯一比原来复杂的地方在于这个元素是由10int组成的数组,而不是基本类型。这样,我们可以把pa当成二维数组名来使用,pa[1][2]a[1][2]取的也是同一个元素,而且paa用起来更灵活,数组名不支持赋值、自增等运算,
而指针可以支持,pa++使pa跳过二维数组的一行,指向a[1]的首地址。

四, 函数类型和函数指针类型

C 语言中,函数也是一种类型,可以定义指向函数的指针。我们知道,指针变量的内存单元存放一个地址值,而函数指针存放的就是函数的入口地址(位于.text段)

函数指针实例:


f 就是一个函数指针,函数的参数为const char * ,函数的返回值为voidf 就只指向这种函数的指针。say_hello 这是这种类型的指针,可以赋值给fsay_hello 是一种函数类型,而函数类型与数组类型类似。做右值使用时自动转换成函数指针类型。所以可以直接赋值给f 。如果写成void (*f)(const char *) = &say_hello;,把函数say_hello先取地址再赋给f ,就不需要自动类型转换了。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值