C语言-指针

作者: Jimmy_L_Wang | 来源:发表于2018-09-28 20:28 被阅读0次

指针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*pffoo的别名(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 < 5; i++) {
        printf("&a[%d] = %p p+%d = %p\n", i, &a[i], i, p+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, 是pi的加法运算。和算术类型的数值间的加法运算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;    //OK

int 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]进行初始化。

函数间数组的传递,是以指向第一个元素的指针的形式进行的。在被调用的函数中作为指针接收的数组,实际上就是调用方传递的数组。

相关文章

  • C语言05- 指针

    C语言05- 指针 13:指针 指针是C语言中的精华,也是C语言程序的重点和难点。 13.1:指针定义与使用 指针...

  • 02-C语言的指针

    02-C语言的指针 目标 C语言指针释义 指针用法 指针与数组 指针与函数的参数 二级指针 函数指针 指针在C中很...

  • C语言指针总结大学霸IT达人

    C语言指针总结大学霸IT达人 C语言的指针是C语言区别其它语言的最主要的特定之一。有了指针,C语言就可以抛开所有束...

  • 带小白学C语言指针

    C语言里指针才是C语言的开始和指针;C语言里基本所有东西都是由指针演变而成; 指针是指向地址的变量,类型就是指针...

  • 在Swift中使用C语言的指针

    在Swift中使用C语言的指针 在Swift中使用C语言的指针

  • [Swift]结构体指针操作

    C语言的指针操作 在c语言中申明一个变量并通过指针修改该变量的值 a value is 2 c语言操作结构体指针操...

  • Go语言-指针

    Go语言中的指针不同于C语言,Go语言的指针使用方法要简单很多。当然和C语言从指针定义到指针的使用都有很大的不同。...

  • C语言中的指针与数组

    C语言中的指针与数组 @(C语言)[排序算法, 快速排序, C实现] 引言 相信指针与数组是不少同学在初学C语言时...

  • 指针数组和数组指针

    指针数组|存储指针的数组 在C语言和C++语言中,数组元素全为指针的数组称为指针数组。 例如:int *p[10]...

  • iOS开发 -- C语言基础8(指针)

    iOS开发 -- C语言基础8(指针) 指针是C语言中非常重要的数据类型,如果你说C语言中除了指针,其他你都学得很...

网友评论

    本文标题:C语言-指针

    本文链接:https://www.haomeiwen.com/subject/kxhmoftx.html