c语言指针慕课,C语言-指针

指针pointer

数据类型决定了变量可以表示的数值范围。除此之外,表示变量在内存中生命期范围存储期以及变量名也都是变量的重要属性。

取址运算符-address operator单目运算符`&`     `&a`     取得`a`的地址(生成指向a的指针)

取址运算符&的功能是取得对象的地址。对于使用register关键字声明的寄存器对象,不能加上取址运算符&.

指针int foo = 178;int *pf = &foo;

printf("pointer value == %d\n", *pf);printf("foo value == %d\n", foo);//pointer value == 178//foo value == 178

上例中,变量名前加*,通过该声明定义了指向int型变量的指针变量,他们指向的是int型变量。

以上的两种形式可以理解为:int型变量: 保存整数的盒子

指向int型变量的指针变量:保存存放整数对象的地址的盒子。

指针运算符单目运算符 *    *p     p指向的对象

根据上例,可以得出:

*pf就是foo,*pf是foo的别名(alias)

解引用

通过在指针前写上指针运算符*来访问该指针指向的对象,称为解引用(dereference)

例: *pf

指针的类型

指向Type型对象的指针,即Type*型指针。并不是表示指向OO号,更确切地说是指向以OO号为首地址的Type型对象

空指针 - null pointer

什么也不指向的特殊指针是空指针(null pointer),表示空指针的对象式宏NULL是空指针的常量。

指针和数组

数组名原则上会被解释为指向该数组起始元素的指针。指针p指向数组中的元素e时,

p + i为指向元素e后第i个元素的指针

p - i为指向元素e前第i个元素的指针void array_pointer(void){    int a[5] = {1, 2, 3, 4, 5};    int *p = a;

for (int i = 0; i 

}

} /*

&a[0] = 0x7ffeefbff4f0 p+0 = 0x7ffeefbff4f0

&a[1] = 0x7ffeefbff4f4 p+1 = 0x7ffeefbff4f4

&a[2] = 0x7ffeefbff4f8 p+2 = 0x7ffeefbff4f8

&a[3] = 0x7ffeefbff4fc p+3 = 0x7ffeefbff4fc

&a[4] = 0x7ffeefbff500 p+4 = 0x7ffeefbff500

*/

数组名在什么情况下不被视为指向起始元素的指针作为sizeof运算符的操作数出现时sizeof(array)不会生成指向起始元素的指针的长度,而是生成数组整体的长度作为取址运算符&的操作数出现时&数组名不是指向起始元素的指针的指针,而是指向数组整体的指针。

指针运算符和下标运算符当指针p指向数组中的元素e时,

指向e后第i个元素的*(p + i),可以写为p[i];

指向e前第i个元素的*(p - i),可以写为p[-i]Type*型指针p指向Type型数组a的起始元素a[0]时,指针p的行为就和数组a本身一样。数组的下标表示位于起始元素后的第几个元素的位置,因此必须从0开始。虽然可以为指针加上整数,但是指针之间相加是不可以的

下标运算符的操作数* (p + i)

括号内的p + i, 是p和i的加法运算。和算术类型的数值间的加法运算a + b等同于b + a一样, p + i也等同于i + p。

也就是说, * (p + i) 和 * (i + p)是等价的。

这样一来,是不是访问数组元素的表达式p[i]也可以写成i[p]呢。实际上确实是可以的。

下标运算符[],是具有两个操作数的双目运算符。

其中一个操作数的类型是:指向Type型对象的指针

另一个操作数的类型是:整数类数据类型

下标运算符[]的操作数的顺序是随意的。就像a + b等同于b + a一样, a[3]和3[a]也是一样的。

下标运算符[]所生成的值的类型是Type型指针p指向数组a的起始元素a[0]时,a[i]    *(a + i)        p[i]      *(p + i)

这4个表达式表示的都是相同的元素。实际上a[i]   i[a]   *(a + i)   *(i + a)    p[i]    i[p]    *(p + i)    *(i + p)

这8个表达式表示的都是相同的元素。

数组和指针的不同点int *p;int y[5];

p = y;    //OKint a[5];int b[5];

a = b;    //错误赋值表达式的左操作数不可以是数组名。

数组的传递

在函数间传递数组时,可以灵活应用指针和数组的相似性。void arr_set(int v[], ...){   /*----do sth------*/}void arr_set(int v[5], ...){   /*-----do sth-----*/}void arr_set(int *v, ...){   /*-----do sth-----*/}

以上三个函数, 第一个和第二个都可以解释为第三个。 形参V的类型不是数组, 而是指针。即使像第二个函数那样指定元素个数,该值也会被无视。

调用上述arr_set函数时,int*型的形参V将使用实参a,即&a[0]进行初始化。

作者:Jeremy_L_Wang

链接:https://www.jianshu.com/p/682fc61e04c7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值