C指针浅谈

前言:

在C语言的学习及使用中,包括阅读github上的各种源代码都少不了绕得人眼花缭乱的指针。本文简单讨论一下指针及变量的关系,希望能起到抛砖引语的作用,和大家一起探讨学习。

环境:

  • 编译器:Clang
  • 编译命令:gcc test_main.cpp -o test_main
  • 操作系统:MacOS

内容:

普通变量

Code:

int main(int argc, char* argv[]){

    int a;
    printf("&a = %d    a = %d\n",&a,a); //&a = 1547790796    a = 0

    return 0;
}

OutPut:

&a = 1547790796 a = 0

这里我们剋看到变量a已经被分配了内存,这块内存的地址为‘1547790796’,内存中存储着一个整形数字0。

接下来我们给这个变量赋值
Code:

int main(int argc, char* argv[]){

    int a;
    printf("&a = %d    a = %d\n",&a,a); //&a = 1547790796    a = 0
    a = 723;
    printf("&a = %d    a = %d\n",&a,a); //&a = 1547790796    a = 723

    return 0;
} 

OutPut:

&a = 1547790796 a = 0
&a = 1547790796 a = 723

由于已经被在内存中开辟了一块区域,所以直接赋值操作并没有问题。

指针

Code:

int main(int argc, char* argv[]){

    int a;
    printf("&a = %d    a = %d\n",&a,a);  //&a = 1547790796    a = 0
    a  = 723;
    printf("&a = %d    a = %d\n",&a,a);  //&a = 1547790796    a = 723

    int *b;
    printf("&b = %d    b = %d\n",&b,b); //&b = 1547790784    b = 0
    b  =  &a;
    printf("&b = %d    b = %d    *b = %d\n",&b,b,*b); //&b = 1547790784    b = 1547790796    *b = 723

    return 0;
}

OutPut:

&a = 1547790796    a = 0
&a = 1547790796    a = 723
&b = 1547790784    b = 0
&b = 1547790784    b = 1547790796    *b = 723

我们发现在声明了指针之后并不会分配内存,指针直接指向了地址0,所以在这个时候使用静态语句直接初始化会导致程序运行时异常中断(eg: *b = 723,访问无权限操作的内存,在程序的运行状态中,在可访问内存中的越界行为不会导致程序中断,而访问了无权限内存时则会被操作系统终止)

当我们把a的地址赋给b之后,*b就可以正式的代表一个int类型的变量了,而&b则是这个指针的地址,也就是一个 **int 类型的变量。在之后的程序中我们会看到不论是第几重指针,指针本身都有一个地址,而指针本身在声明时并未被初始化,所以指针有指针本身的地址,却指向了不可操作的一块内存,只有当指针指向了一个初始化的地址之后,指针本身才可用于访存。

Code:

int main(int argc, char* argv[]){

    int a;
    printf("&a = %d    a = %d\n",&a,a);  //&a = 1547790796    a = 0
    a  = 723;
    printf("&a = %d    a = %d\n",&a,a);  //&a = 1547790796    a = 723

    int *b;
    printf("&b = %d    b = %d\n",&b,b); //&b = 1547790784    b = 0
    b  =  &a;
    printf("&b = %d    b = %d    *b = %d\n",&b,b,*b); //&b = 1547790784    b = 1547790796    *b = 723

    int **c;
    printf("&c = %d    c = %d\n",&c,c); //&c = 1547790776    c = 0
    c  =  &b;
    printf("&c = %d    c = %d    *c = %d    **c = %d\n",&c,c,*c,**c); //&c = 1547790776    c = 1547790784    *c = 1547790796    **c = 723

    int ***d;
    printf("&d = %d    d = %d\n",&d,d); //&d = 1547790768    d = 0
    d  =  &c;
    printf("&d = %d    d = %d    *d = %d    **d = %d    ***d = %d\n",&d,d,*d,**d,***d); //&d = 1547790768    d = 1547790776    *d = 1547790784    **d = 1547790796    ***d = 723

    return 0;
}

OutPut:

&a = 1547790796    a = 0
&a = 1547790796    a = 723
&b = 1547790784    b = 0
&b = 1547790784    b = 1547790796    *b = 723
&c = 1547790776    c = 0
&c = 1547790776    c = 1547790784    *c = 1547790796    **c = 723
&d = 1547790768    d = 0
&d = 1547790768    d = 1547790776    *d = 1547790784    **d = 1547790796    ***d = 723

指针及指针指向内存的地址

当我们要初始化指针时,可以选择使用malloc函数。

Code:

int main(int argc, char* argv[]){

    int a;
    printf("&a = %d    a = %d\n",&a,a);  //&a = 1547790796    a = 0
    a  = 723;
    printf("&a = %d    a = %d\n",&a,a);  //&a = 1547790796    a = 723

    int *b;
    printf("&b = %d    b = %d\n",&b,b); //&b = 1547790784    b = 0
    b  =  &a;
    printf("&b = %d    b = %d    *b = %d\n",&b,b,*b); //&b = 1547790784    b = 1547790796    *b = 723

    int **c;
    printf("&c = %d    c = %d\n",&c,c); //&c = 1547790776    c = 0
    c  =  &b;
    printf("&c = %d    c = %d    *c = %d    **c = %d\n",&c,c,*c,**c); //&c = 1547790776    c = 1547790784    *c = 1547790796    **c = 723

    int ***d;
    printf("&d = %d    d = %d\n",&d,d); //&d = 1547790768    d = 0
    d  =  &c;
    printf("&d = %d    d = %d    *d = %d    **d = %d    ***d = %d\n",&d,d,*d,**d,***d); //&d = 1547790768    d = 1547790776    *d = 1547790784    **d = 1547790796    ***d = 723

    b  =  (int*)malloc(sizeof(int*)*1);
    *b  =  327;
    printf("&b = %d    b = %d    *b = %d\n",&b,b,*b); //&b = 1547790784    b = 1740636288    *b = 327

    return 0;
}

OutPut:

&a = 1547790796    a = 723
&b = 1547790784    b = 0
&b = 1547790784    b = 1547790796    *b = 723
&c = 1547790776    c = 0
&c = 1547790776    c = 1547790784    *c = 1547790796    **c = 723
&d = 1547790768    d = 0
&d = 1547790768    d = 1547790776    *d = 1547790784    **d = 1547790796    ***d = 723
&b = 1547790784    b = 1740636288    *b = 327

我们发现malloc分配出来的地址和其他的地址差距时比较大的,这是因为在函数中声明的临时变量被存储在栈当中,而通过mallloc分配的内存则在堆中。而存储在栈那的变量发生越界时则基本上都会踩到已经分配出去的内存。

我们知道栈区内存是连续分配的,入栈出栈的操作仅仅改变了栈顶指针,所以,当我们向栈区连续压入数据的时候,内存地址也必然是连续的,但是在这里我们发现&a到&b有12个字节的长度,而其他的变量之间长度都是8个字节,这是因为只有变脸a在声明时被分配了4个字节的存储空间存放这个int类型的值,再加上指针本身的8个字节,正好12个字节。

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

推荐阅读更多精彩内容