浅解C语言指针

作者: Python编程导师 | 来源:发表于2018-12-20 19:16 被阅读4次

    说到「指针」一定会联系到 C 语言。虽然 java/go/php/python 等 C 系语言都属于 C 的衍生品,但“指针”只是在 C 语言中大行其道。也正时由于指针,使C 语言成为开发大型系统(操作系统、游戏引擎等)的不二之选,可以说指针是 C 语言的灵魂。

    同时,能不能灵活的使用指针,也是衡量 C 程序员的功能底的标准之一。

    内存与指针

    一个程序运行所需的所有数据都存储在内存中,CPU 通过访问内存获取「指令信息」与「数据信息」,进而进行逻辑操作...

    而记录这些信息在内存中位置的变量即为「指针」。

    内存地址与指针变量

    变量:程序中把代表着一定信息的符号称为变量,如int a = 10

    内存地圵:信息在内存中的位置,如 0x7ffd4506b0e4

    变量与内存地址:程序运行时需要把 a=10 这个信息存储在内存中,存储的这个位置就是地址 &a

    指针变量:首先它是一个普通的符号 int *p = &a,不过它对应的内存中存储的信息是一个地址 0x7ffd4506b0e4

    指针变量与内存地址:存储指针变量的内存中的值是 0x7ffd4506b0e4,存储的位置是 &p

    指针变量与指针类型

    指针变量 p 是一个值

    如 0x7ffd4506b0e4,代表其在内存中的某个位置,*p 即为访问这个位置

    通过修改 p 的值,理论可以通过 *p访问内存的任意位置

    指针类型告诉程序应该怎么理解这块内存

    int *p=0x7ffd4506b0e4, 代表内存在 0x7ffd4506b0e4 处存储的值是一个 int

    float *p=0x7ffd4506b0e4, 代表内存在 0x7ffd4506b0e4 处存储的值是一个 float

    struct XXX *p=0x7ffd4506b0e4, 代表内存在 0x7ffd4506b0e4 处存储的值是一个 XXX 这个结构

    对于 int *p 在访问 *p 时,程序在内存中取 sizeof int个字节

    对于 struct XXX *p 程序在访问内存时读取 sizeof (sruct XXX) 个字节

    int * 解析思路 * int 我是一个指针,我指针向一个 int 结构

    struct X{    int a;    int b;}X 中的偏移 offset    &((struct X*)(p)->b) - p技巧: offset =  &((struct X*)(0)->b)    把 0 当作某 X 数据的指针,则 offset 处存储的即为 bshort a = 0x1122;char c  = *(char*)(&a)c == 0x22 // 小端存储c == 0x11 // 大端存储

    函数指针

    如上所属,程序运行中所需的信息(函数体、数据)需要放在内存中。而指针的存在即为了定位内存中的这些数据。

    用于定位数据的指针即为变量指针;用于定位数据的指针即为函数指针

    void (*f)(int) = 0x7ffd4506b0e4: 代表内存在 0x7ffd4506b0e4 处存储的是一个函数 (接受参数 int 返回类型 void)

    voidoutput(inta){printf("%d\n",a);}void(*f)(int)=&output;// 习惯性写作: void (*f)(int) = output; f(10);// 即会输出 10

    一切皆是指针

    因为一切都在内存里,因为一切都是内存里的数据(0/1),因为 CPU 正常工作依靠在内存中读写数据。

    所以 C 语言中的所有符号都是指针

    普通变量与指针变量

    inta=10;// 假设 &a 等于 0x7ffd4506b0e4a+=2

    程序编译结果 (涉及编译链接原理)

    声明 10 要放在 0x7ffd4506b0e4 内存处

    a += 2 直接会编译成 *(0x7ffd4506b0e4) += 2

    因为 int a,程序把 0x7ffd4506b0e4 的数据按 int 解析

    inta=10;// 假设 &a 等于 0x7ffd4506b0e4int*p=&a;// 假设 &p 等于 0x7ffd4506a111(*p)+=2

    程序编译结果

    声明 10 要放在 0x7ffd4506b0e4 内存处

    程序执行时

    0x7ffd4506b0e4 被存储到 0x7ffd4506a111 位置

    (*p) += 2 在 0x7ffd4506a111 读取到 0x7ffd4506b0e4

    *(0x7ffd4506b0e4) += 2 因为 int *p,程序把 0x7ffd4506b0e4 的数据按 int

    指针语法糖

    指针的指针

    inta=10;int*p1=&aint**p2=&p1// 即 p2 存的是一个指针的地址

    int ** 的解析方式即 ** int: 我是一个指针,我指针一个指针结构,这个“被指向的指针结构”指向一个 int 结构

    数组指针与指针数组

    chara[10];char*p=a;// 这个指针指向数组char*p[10];// [10]*char 这是一个长为10的数组,里面存了一堆指针,指针指向 char 结构

    指针常量与常量指针

    charachar*constp=&a;// const * char  p 中一个常量指针,指针 charcharconst*p=&a;// * const char  p 是一个指针,指向 const char

    因为指针过于灵活,需要限制指针功能

    char * const p p 不能再赋其它值

    char const *p *p 不能再赋其它值

    函数指针与返回指针的函数

    char*func()// 返回指针的函数void(*f)(int);// 函数指针 

    返回指针的函数指针

    char*(*f)(int);

    返回函数指针的函数

    intf1(inti){returni*2;}int(*f1())(int){returnf2;}printf("%d",f1()(4));

    返回函数指针的函数指针

    typedefint(*t())(int);intf1(inti){returni*2;}int(*f2())(int){returnf1;}intmain(){t*func_t=f2;printf("%d",(*func_t)()(2));}

    相关文章

      网友评论

        本文标题:浅解C语言指针

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