C语言指针1

一:1、地址:内存单元的编号

    内存单元的值:内存单元中存放的内容

    通过地址可以找到内存单元格,然后再取出内容

    2、指针:就是地址

    3、对变量进行数据存取有几种方式

    两种:直接存取     int a=10;     a=a+10;

    间接存取     通过指针

二: 1、指针变量

    就是用来存放(指针)地址的变量

    注意:指针(地址)和指针变量是两码事

    指针变量使用流程:先定义   ---> 初始化  -->使用

    2、指针变量定义

    格式:数据类型  *指针变量名;

    指针变量名 严格遵守标识符命名规范

    int a;

    char c;

    double d1;

    int *p;  //描述:定义了一个指针变量,变量名是p ,它可以存放一个整型(int)数据的地址

    注意:

    1)指针变量只能存放地址

    2)int *p中,"*"表示定义一个指针变量

    3)指针变量也有作用域(全局的、静态、局部)static修饰局部变量局部变量的生命周期延长

    4)定义指针变量指向的话,要注意指针的类型,因为当使用指针操作指针指向内存单元内容时,会按照指针的类型到内存中寻址,因此可能会出现问题。

    3、指针变量的初始化

    把谁的地址给指针变量,就可以理解为,这个指针变量指向这个变量

    1)定义的同时初始化

    “&” 用此符号可以取得一个变量的地址

    int a;

    char c;

    double d1;

    int *p1=&a;   //&a 获取的变量a的地址    scanf("%d",&a);

    char *c1=&c;

    double *dp=&d1;

    int *p2 = &c;(错误的,p2只能存放一个int型数据的地址)

    int *p3 = 100;(错误的,p3用来存放地址的,不能存放整型的数

                   2)先定义,后初始化

                   1)变变量的地址进行初始化

                   int *p3;

                   p3 = &a;  //给p3指针进行初始化

                   2)用指针变量,初始化另外一个指针

                   int *p4=&a;

                   int *p5;

                   p5 = p4; //p4存放的时一个地址,可以直接赋值给p5

                   3)指针变量可以初始化为NULL

    NULL 空 (不是0   “ ”  ‘ ’)

    int *p2 = NULL

    用0赋值为空

    int *p3=0;

    错误:

    int *p6=&a;

    char *c2=&c;

    int *p7 = c2; 错误的,因为p7只能存放int型数据的地址 c2是一个char型变量的地址

三:指针变量的引用:

    &  获得一个变量的地址

    *  两种用法

    1)在定义指针变量的时候,表示定义的时一个指针变量

    2)*指针变量名   表示取得指针变量中存放的那个地址对应的存储单元的值

    int a = 9;    int *p1 = &a;

    *p1  9, //获取a的地址,对应的值

四:指针使用场景:

    指针的使用场景1:

    在被调函数中,访问主调函数中的变量

    例如:void change(int *p){

               *p =  100;

             }

    指针的应用场景2:

    一个函数可以有多个返回值(原理上同指针使用场景1)

    例如:void yunsuan(int a,int b,int *add,int *jian,int *cheng,int *chu){

        

        *add = a+b;  // *add 访问add指针变量存放的地址的对应存储单元的内容

        //  add = 0x01    *0x01  取得地址对应的值

        *jian = a-b;

        *cheng = a*b;

        *chu  = a/b;

    }

五:多级指针:

    int a = 10; int p = &a; int **p2 = &p; int ***p3 =&p2;

    printf("a = %d ",a);        //10

    printf("a addr = %p ",&a);  //a的地址

    printf("*p = %d ",*p);      //10

    printf("p addr = %p ",&p);  //指针变量p的地址

    printf("*p2 = %p ",*p2);    //p的内容,a的地址

    printf("**p2 = %d ",**p2);  //10 *(*p2)  = *(a的地址) = 10

    printf("***p3 = %d ",***p3); // 10 **(*p3) = *(*p2) = *p = 10

六:指针为什那么要区分类型:

    疑惑点:

    1)数据占用的字节数是不一样的,但是为什么指针用都8个字节

    指针变量用来存放地址,地址的占用的字节数是一样的,

    2)既然指针变量都是占用8个字节,为什么要还有区分指针类型呢

    int a = 266;

    char *pc = &a;

    printf("*pc = %d ",*pc);// 打印结果有问题?因为char类型的指针会在内存中寻址,寻址一个字节的内存,而int类型的变量占四个字节; 

    

七:1、数组的指针的概念:

    数组元素的指针

    定义一个指针变量,指向数组的某一个元素

    注意:

    int a[5];

    int *p = &a[1];

    int *p1 = &a[0];     //&a[0] == 数组的首地址  ==  数组名

    //p1指向数组了

    2、用数组指针引用(访问)数组元素

    引入数组指针的概念主要是为了

    ,用指针引用数组的每个元素(其实就是用指针间接访问a[0]  a[1]。。。。。)

    1)用数组名引用数组的元素

    a[0]   a[1] ....... (用数组名直接访问)

    用数组的首地址(数组名)进行访问

    a+0 --> a[0]   a+1 --> a[1]    a+2  --->a[2]

    2)用指针引用数组的元素

    用数组指针访问数组元素

    int *p=a;

    int *p1=&a[0];

    p+1    a[1]    //a+1

    p+2    a[2]

    3)疑惑:既然用数组名和数组指针都可以访问数组,为什么还要使用指针?

    使用指针比较灵活

    体现在:

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

        printf("p+%d = %d ",i,*(p++)); //*p   p = p+1  *p-->a[1]

    }

    4)数组名和指针变量的区别

    int  a[10];    //a数组名  是一个常量  a+1  a+2 ;

    int *p = a;    //p是一个指针变量,p = p+1 可以,p++

    注意:1>p+1指指针变量所指向地址的偏移量,如果int行指针变量偏移4个字节

         2>数组a++不正确,因为数组名a为常量,不能a=a+1,

 

八: 指针数组:

    数组中的每一个元素都是地址(指针)

    int a[3][3]={1,2,3,4,56,7,8,120,11};

    //定义一个指针数组名为pa 有三个元素,a[0],a[1],a[2]三个地址

    int *pa[3]={a[0],a[1],a[2]};

    *(pa+1)

    注意:数组指针是指向数组的指针,指针数组是存放指针(地址)的数组

原文地址:https://www.cnblogs.com/-boy/p/4044337.html