Leetcode中 ** returnColumnSizes到底是什么?

概 述

刷过题的朋友肯定见过这个 ** returnColumnSizes,或者是* returnSize. 说实话我看到*returnSize的时候是理解的,但是一到了二级指针就止不住的懵逼,在自己研究讨论了两个小时之后,我想明白了。如有疑问请打脸。

其实 ** 的使用,和交换两个整数的 swap 函数是同一个道理。


使用 returnSize 和 returnColumnSizes 的原因

我的理解是,你返回一个数组的时候,只能返回它的指针,但是官方检测的时候到底要检查多少个数据呢?智能检测也太耗资源了,所以需要你告诉它,我前 returnSize 个数据是有用的,后面的数据只是我防止溢出多创建的,让它检查这么多个就好啦。

首先大家要知道这个 returnColumnSizes 在主函数中应该是一个一维数组,每个元素代表了当前排有多少个有效的列,一般这种题会有一个配套的 returnSize 代表共有多少排,这个一维数组,配合着排的总数,就可以让 Leetcode 后台去检查你的答案了。

swap函数

所有指针的入门教学,都会用一个交换函数来告诉你指针的必要性,

如果你对此耳熟能详,请直接跳到下一个分割线。


void swap(int x, int y) {

    int temp;

    temp = x;

    x = y;

    y = temp;

}

int main(void)

{

    int x = 1;

    int y = 0;

    printf("x is %d, y is %d\n", x, y);

    swap(x, y);

    printf("x is %d, y is %d", x, y);   

}
如果我们只是把主函数的 x,y 传进 swap 函数里面,
那么虽然它们在交换函数中被改变了,但是在主函数中并不会改变。
只有你把地址传进去,通过解引用的方式才能够成功改变两个数。
void swap(int *x, int *y) {

    int temp;

    temp = *x;

    *x = *y;

    *y = temp;

}

int main(void)

{

    int x = 1;

    int y = 0;

    printf("x is %d, y is %d\n", x, y);

    swap(&x, &y);

    printf("x is %d, y is %d", x, y);   

}
第一种方法不能改变x,y,是因为在把它们传进函数swap的时候,
其实是复制了他们的值给swap中的参数,而他们本身什么也没做。

第二种方法可以成功交换x,y,是因为系统在保存 x,y的内存地址上面,
直接对他们在内存上储存的值进行了操作。

众生平等,指针也一样

参考swap函数,如果我们把一个指针传进一个函数中,然后想要去改变这个指针上面保存的地址的时候,主函数的指针保存的地址同样不会改变。

下面用一段代码来解释:


void change(int *ptr);

int main(void) 

{

    int *p = NULL;

    change(p);

    printf("%p", p);

}

void change(int *ptr) {

    ptr = 0xff00;          // 给 ptr 赋值一个地址,在函数中,ptr确实会改变,但离开函数块后又会变回去

}

如果你在这里开启调试模式,你会发现,原函数中的ptr的地址,并不会因为进入change()而被改变。

那么实际的leetcode主函数到底是怎么写的呢?我写了一个小例子,在函数中使用了 **

void change(int **ptr);

int main(void) 

{

    int *p = NULL;

    change(&p);

    for (int i = 0; i < 10; i++) {

        printf("%d\n", p[i]);

    }

}

void change(int **ptr) {

    int *res = (int *)malloc(sizeof(int) * 10);

    for (int i = 0; i < 10; i++) {

        res[i] = i;

    }

    *ptr = res;

}
我们可以看一下change的最后一条代码:

*ptr = res;

请问ptr是啥,ptr不就是你传进来的地址?
回主函数找一下,哦~~,原来ptr就是 &p 啊,那翻译过来不就是:

*(&p) = res;          

这不就等于  p = res;  嘛,
相当于我在主函数里建立了一个一级指针,但是我不知道它该指向哪里,
答案里面建立了一个一维数组,我现在告诉主函数里面的一级指针,你指向我这个res就好了。

我不想这么麻烦,行吗? 不行!

我要是不想这么麻烦,不想用 

*(&p) = res;  

可以么? 为什么我不直接把主函数中的一级指针直接传进去,然后在直接把 res 赋值给 ptr 呢?

反正         *(&p) = res;      和     p = res;                  完全等价嘛!!!

代码我都给你改好了:


void change(int *ptr);

int main(void) 

{

    int *p = NULL;

    change(p);

    for (int i = 0; i < 10; i++) {

        printf("%d\n", p[i]);

    }

}

void change(int *ptr) {

    int *res = (int *)malloc(sizeof(int) * 10);

    for (int i = 0; i < 10; i++) {

        res[i] = i;

    }

    ptr = res;

}

我可以保证这个程序不会如你想的一样运行,原因在上个分割线,众生平等,指针也一样 那里解释的很清楚。

指针上面,保存着一个地址。当你把指针传入一个函数中的时候,你可以改变这个地址上面保存着的 值 ,但是你没办法改变 原函数 中,这个指针保存的地址。

可能听起来有点抽象,之后我学一下iviso画个图再来补充下就很容易懂了。

那么我们怎么样才能把,这个指针 上面保存的地址,在其他函数中直接给改了呢?简单啊,你把这个指针的地址传进去不就行了。


如果你把 &p 传入 一个 参数是 ** 的函数,那么你就可以通过

*(&p) = res; 

这条代码改变了啊。同样,你传入的这个 &p 也永远没法 改变原函数中的 &p,但是你改变了原函数中的 p。

如果讲到这里,你还是不懂,那就别看了,自己去动手,把我上面的代码都运行一下,调试一下,你就懂了,光看还是有点难理解的。


指针误区

很多同学可能看完我写的东西产生了质疑,指针不就是用来改变值的么?怎么就不行了呢?

那么我们看一下下面指针改变值的成功例子。


void change(int *p) {

    p[0] = 5;

    p[1] = 6;

    p[2] = 7;

}

int main(void) {

    int *p = (int *)malloc(sizeof(int) * 3);

    for (int i = 0; i < 3; i++) {

        p[i] = i;

        printf("%d ", p[i]);

    }

    change(p);

    printf("\n");

    for (int i = 0; i < 3; i++) {

        printf("%d ", p[i]);

    }

}

这里确实成功改变了,但是我们改变的是,指针p上面保存的地址,在内存中储存的值,而不是改变了指针p上保存的地址。


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