zoukankan      html  css  js  c++  java
  • C指针分析详解

    局部变量和全局变量初始化区别

      局部变量,在未初始化情况下,初值为随机值。C规范对该初值并没有做规定,具体实现由编译器决定。如VC/VS等编译器,会将初始值值为0xCCCCCCCC, 而GCC等编译器则是不可预知的随机值。

      全局变量和静态局部变量(带static修饰的局部变量)。即定义在函数外,不属于任何一个函数的变量。这两种默认初值为0.

     


    指针:指针其实是一个地址。

    指针赋值:一个地址的赋值。

    空指针:即 int *p=NULL ;  //等于NULL

    野指针:即 int *p;    //只声明,不定义(赋值)

    指针变量:int  *p =&a;  //*p称为指针变量,无论是声明时候什么类型,指针变量只占有4个字节。

    &:取地址符号

    *:指针符号,指向一个储存空间,也可以取出存储空间的值

    数字名:数组名是一个地址(首地址),是一个常量,不允许重新赋值   //第一个元素的地址。

      

    对一级指针,二级指针进行操作:

    其实:&与*是一个反运算符

    一级指针:*p

      (*p)++:括号优先级大,所以直接执行(*p)操作,取出该指针所对应的值,然后对值进行加1操作。

      *p++:++与*优先级相同,从右往左操作:先执行p++,由于是“++”号是后加加号,所以会在整条语句执行完后再对P自加1,所以先输出*p,然后指针再+1。

      *(p+1):括号优先级大,与*p++类似。

      *p:直接取出指针所对应的数值。

      *++p:++与*优先级相同,从右往左操作:先执行++操作,再执行*。++p先把指针+1,然后再取加1后的值。

      *(++p):括号优先级大,与*++p类似。

    #include<stdio.h>
    int main(void){
        int a[]={1,2,3,4,5};
        int *p=a;
    
        printf("++(*p):%d 
    ",++(*p));//2
        printf("(*p)++:%d 
    ",(*p)++);//2
        printf("a[0]:%d
    ",a[0]);//3
        
        printf("*p++:%d 
    ",*p++);//3
        printf("*(p++):%d 
    ",*(p++));//2
        printf("*p:%d 
    ",*p);//3
        
        p=a;//a指针重新回到a[0] 
        printf("a[0]:%d
    ",a[0]);//3
        printf("*++p:%d 
    ",*++p);//2
        printf("*(++p):%d 
    ",*(++p));//3
        
        return 0;
    }

    二级指针:**p2

    #include<stdio.h>
    int main(void){
        int a=10;
        int *p=&a;
        int **pp;
        pp=&p;
        printf("&a:%p
    ",&a);//000000000062FE4C
        printf("&p:%p
    ",&p);//000000000062FE40
        printf("&pp:%p
    ",&pp);//000000000062FE38
        printf("p:%p *p:%d
    ",p,*p);//000000000062FE4C 10
        printf("pp:%p **p:%d %d
    ",pp,**pp,*(*pp));//000000000062FE40 10 10
        printf("pp:%p  &p:%p  
    ",pp,&p);//000000000062FE40  000000000062FE40
        printf("*pp:%p  p:%p 
    ",*pp,p);//000000000062FE4C 000000000062FE4C
        printf("**pp:%d  *p:%d
    ",**pp,*p);//10  10
        return 0;
    }

     

    由图所示:

        p: p里面存储的是a的地址。

      *pp二级指针: 取一级指针的数值,也就是&a,但是&a是一个地址,所以取出来的是一个地址。

      **pp二级指针:可以看成*(*pp),先取*p里面的值,取出来之后是&a,接着就是*(&a),结果10。


     常量指针:int const *p;

    1.通过该指针不可以修改它所指向的存储单元里面的值【只有读的权限,没有修改,如果要修改存储单元里面的值,需要用一个指针去修改】

    2.指针指向地址可以被修改【指向地址】

     

    #include<stdio.h> 
    int main(void){
        int a=10;
        int b=9;
        int const *p =&a;
        *p=11;//常量指针报错,指向的存储单元的值,不可以被修改 
        p=&b;
        
        printf("p:%d",*p) ;
        
        return 0; 
    }

    指针常量:int * const p 

    1.指针本身即地址不可以被修改。【用二级指针修改存储单元里面的值】

    2.通过该指针可以修改它所指向的存储单元的值。

    【与常量指针相反】

    #include<stdio.h> 
    int main(void){
        int a=10;
        int b=9;
        int *const p=&a;
        
        *p=11;
        p=&b;//报错,地址不能修改 
        
        printf("p:%d",*p);
        
        return 0; 
    }

    指向常量的指针常量:int const * const p

    1.指针本身即地址不可以被修改。

    2.通过该指针不可以修改他所指向的存储单元的值。

    段的错误(常见问题):

    a.操作了空指针

    b.对野指针进行赋值(操作受保护的内存),也就是已经被占用的内存。

    c.指针指向一个错误的内存(或者说是不存在的内存)。

    d.修改常量区的内容。

    tianjiale菜鸟名企梦
  • 相关阅读:
    线段树(已修改+补题
    畅通工程
    线段树
    charles
    flash
    mysql node pool
    node简单操作mysql的类
    小于任意数字的随机数
    文件系统的移植
    驱动
  • 原文地址:https://www.cnblogs.com/tianjiale/p/9839133.html
Copyright © 2011-2022 走看看