c语言 - *指针 和 &地址

最近在研究oc的底层,全是c/c++的代码,虽然以前学过也写过,其实不怎么用都忘得差不多了。

首先我们来了解一下 *&这两个符号

通俗点儿理解其实&地址就是就是一个存放地址的变量存储空间,当p指针指向某个变量,这时这个p指针里就存放了那个变量的地址。这就是我们常说的指针指向一个地址,意思是通过它能找到以它为地址的内存单元。利用指针我们可以直接获取变量中的值用,要是在指针前加 * 就是取其真值了(也就是被指向的变量的值)

//写一串代码
    int arr[5] = {1,2,3,4,5};
    int * p = &arr[0];

首先初始化了在32位RAM处理器中的arr数组占20个字节(int 占用4个字节,32比特),然后我们定义了 一个int 类型的指针变量p,指针p指向了&arr[0] 也就是 arr数组的第一个元素地址。

声明中: * 表示指针,例如: int p,p是指针,指向整型量。p表示指针指向的整型量的值。
语句中,p表示指针指向的地址。如果p是指针,没有 &p 形式。二、 x指令:
声明中:a是整型量。&a是整型量a的地址,不是指针。
语句中:a是整型量a的值。&另一用途是按位运算符,按位* 是乘号。

此时此刻,你是不是对指针变量和地址有了一定的认知了。指针也不过如此嘛?
在此之前我们先看下下列问题

int arr[5] = {1,3,5,7,9};
arr = ?
arr[0] = ?
&arr = ?
&arr[0] = ?
&arr+1 = ?
&(arr + 1)  = ?   

lldb打印内容:

(lldb) po arr[0]
1

(lldb) po  arr

(lldb) po  &arr
0x00007ffeefbff4c0

(lldb) po &arr[0]
0x00007ffeefbff4c0

(lldb) po &arr + 1
0x00007ffeefbff4d4

(lldb) po &arr[1]
0x00007ffeefbff4c4

(lldb) po (arr + 1)
0x00007ffeefbff4c4

(lldb) po *(arr + 1)
3

先打印了 arr[0] 等于1。
再打印了 arr 什么也没打印出来
再打印了 &arr arr数组的首地址
再打印了 &arr[0] arr数组首元素地址
再打印了&arr + 1未知地址
再打印了&arr[1] arr数组第二个元素的地址
再打印了 arr + 1 arr数组第二个元素的地址
在打印了 *(arr + 1) arr数组第二个元素

此时此刻 其实我们只有一个疑问 arr 到底是什么?
arr 是数组名称, &arr表示数组首地址,arr表示数组首元素地址
这个结论是怎么来的呢?
arr + 1&arr + 1的结果不同

说明一下 地址 + int
后面的int所代表的字节是根据当前地址类型来
假如前面的地址所代表的是元素类型地址那么所加的 元素字节为int * 单个元素的字节
假如前面的地址所代表的是数组类型地址那么所加的 元素字节为int * 数组的字节
然后再根据元素字节获取当前地址

arr + 1 是arr数组第二个元素的地址,所以arr表示数组首元素地址,&arr + 1未知地址 说明此时的地址已经越过了当前数组内的地址

    int arr[5] = {1,3,5,7,9};
    int * p  = (int*)(&arr+1);
    printf("%d\n",*(p-2));
打印7

此时此刻 p 指向&arr + 1的地址 ,也就是超越了数组界限的下一个地址。 我们用p-2往上走了8个字节,也就到了数组的倒数的第二个元素的地址。由此看来 &arr表示数组首地址。

那么猜想一下&arr +2的地址呢?

小试牛刀:

  • 1.请写出以下代码输出
    int a[5] = {1,3,5,7,9};
    int *ptr = (int*)(&a+1);
    printf("%d, %d", *(a + 1), *(ptr - 1));
解析:
&a  :   代指   数组的整体 的地址,这里的    a是数组整体

a+1:   代指    数组的第一个成员,这里的    a是数组首地址
  • 2.写一个标准宏Max,并给出以下代码的输出
int array[5] = {1, 2, 3, 4, 5};
int *p = &array[0];
int max = Max(*p++, 1);
printf("%d %d", max, *p);
参考答案: 1,2
#define Max(X, Y) ((X) > (Y) ? (X) : (Y))
当看到宏时,就会想到宏定义所带来的副作用。对于++、–,在宏当中使用是最容易产生副作用的,因此要慎用。
分析:
p指针指向了数组array的首地址,也就是第一个元素对应的地址,其值为1.
宏定义时一定要注意每个地方要加上圆括号
*p++相当于*p, p++,所以Max(*p++, 1)相当于:
(*p++) > (1) ? (*p++) : (1)
=>
(1) > (1) ? (*p++) : (1)
=>
第一个*p++的结果是,p所指向的值变成了2,但是1 > 1为値,所以最终max的值就是1。而后面的(*p++)也就不会执行,因此p所指向的地址对应的值就是2,而不是3.
扩展:如果上面的*p++改成*(++p)如何?
(*++p) > (1) ? (*++p) : (1)
=>
(2) > (1) ? (*++p) : (1)
=> 
max = *++p;
=> 
*p = 3,max = 3;

3.请写出c语言整型和字符型数组的所有定义方法,并根据该文章写出打印出的相对应的地址代表什么

4.链表和数组的区别

5.单向链表和双向链表的区别

6.请写出以下代码的输出

        int i[] = {10, 20, 30, 40, 50};
        int *pa[] = {i, i+2, i+1, i+4, i+3};
        int **p = pa;

        printf("Initial **p = %d\n", **p);//10
        p++;
        printf("After p++, the **p = %d\n", **p);//30
        ++*p;
        printf("After ++*p, the **p = %d\n", **p);//40
        **p++;
        printf("After **p++, the **p = %d\n", **p);//20
        ++**p;
        printf("After ++**p, the **p = %d\n", **p);//21
Initial **p = 10
After p++, the **p = 30
After ++*p, the **p = 40
After **p++, the **p = 20
After ++**p, the **p = 21
定义分析 : (右结合性)
        int i[] = {10, 20, 30, 40, 50}; //定义一个一维整型数组
        int *pa[] = {i, i+2, i+1, i+4, i+3};//定义一个指针数组pa,pa[0],pa[1]分别执行I数组的某一个元素的地址
        int **p = pa;//定一个二重指针(指向指针的指针)p 指向的是pa的地址既&pa(既指针数组pa的首地址的地址), 

        printf("Initial **p = %d\n", **p);//10
        p++;//p++  运行后表示p指向针数组pa的首地址的下一个地址
        printf("After p++, the **p = %d\n", **p);//30
        ++*p;//右结合性 相当于++(*p),*p表示指针数组pa的第二个元素的值既整型数组i的第3个地址,++后*p指向整型数组i的第4个地址,p指向指针数组pa的第二个元素的地址
        printf("After ++*p, the **p = %d\n", **p);//40
        **p++;//右结合性 相当于**(p++),此时p指向指针数组pa的第二个元素的地址,++后p指向指针数组pa的第三个元素的地址
        printf("After **p++, the **p = %d\n", **p);//20
        ++**p;//右结合性 相当于++(**p),此时p指向指针数组pa的第三个元素的地址,**p则为整型数组的第二个元素的值,++后 **p = 21
        printf("After ++**p, the **p = %d\n", **p);//21
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352