C指针浅谈

作者: Canonzki | 来源:发表于2017-07-02 05:36 被阅读21次

前言:

在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个字节。

相关文章

  • 浅谈C语言数组与指针的关系

    浅谈指针定义细节及其与数组的关系 前言 翁恺老师曾经说过,指针是 C 语言的灵魂,是使 C 语言成为 “C语言” ...

  • C指针浅谈

    前言: 在C语言的学习及使用中,包括阅读github上的各种源代码都少不了绕得人眼花缭乱的指针。本文简单讨论一下指...

  • 浅谈C语言指针

    指针是C语言里最强大的类型,合理的使用指针能够使程序灵活简洁又高小,但是使用不合理的话又会给程序带来灾难性的后果,...

  • c语言指针

    【浅谈关于指针作为参数并改变它的值的问题_C 语言_脚本之家】http://m.jb51.net/article/...

  • 浅谈C/C++的指针,引用

    前言 随手也写一下关于ndk开发中关于引用和指针的大致用法,就不上代码了,简单的写一下。 关于指针* C++可以看...

  • C语言

    C 指针、指针变量、函数指针、指针函数、指针数组、数组指针、C 数组

  • 数组指针/指针数组/函数指针/函数指针数组

    原文地址: 浅谈 数组指针 指针数组 函数指针 函数指针数组... 以及它们之间区别。 首先,先说明一个关系:数组...

  • iOS-空指针,野指针,僵尸对象

    浅谈一下空指针,野指针,僵尸对象。 空指针:没有存储任何内存地址的指针,空指针的值是0; 野指针:指针指向的对象已...

  • 02-C语言的指针

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

  • C语言05- 指针

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

网友评论

  • mmlmml:可以考虑画下图.如果没基础.看着估计头疼.类似于int** 这种在c语言里含义较多..可以理解为int * 的地址.也可以理解为.int*的数组..看代码的时候有什么好办法区分么.
    Canonzki:@李龙杰 似乎并没有…就跟做阅读理解一样…联系上下文吧……

本文标题:C指针浅谈

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