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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,423评论 3 44
  • 1. 变量 不同类型的变量在内存中占据不同的字节空间。 内存中存储数据的最小基本单位是字节,每一个字节都有一个内存...
    C语言学习阅读 1,278评论 0 4
  • 前言:指针是 C语言一个重要概念,也是C 语言的一个重要特色。使程序简洁、紧凑、高效。指针乃是C之精华。 数据在内...
    潇湘候晨雪阅读 754评论 0 0
  • 第十章 指针 1. 地址指针的基本概念: 在计算机中,所有的数据都是存放在存储器中的。一般把存储器中的一个字节称为...
    坚持到底v2阅读 1,057评论 2 3
  • 前言 最近真的是忙的不可开交,公司一直给安排任务,连学习和写笔记的时间都没有了,落下好几次课的笔记都没有写,所以我...
    Xiho丶阅读 1,507评论 1 12