美文网首页
C语言指针小结

C语言指针小结

作者: 凌云struggle | 来源:发表于2019-08-04 22:49 被阅读0次

    前言:指针的学习

       在c语言的学习过程中,指针的学习无疑是其中的一道难关,相对来说比较复杂,但是只要从地址和内存管理两方面理解指针,你也许就会发现指针并没有想象中那么难,希望下面的内容能解决你在学习指针中的困扰。

    一、指针介绍

    1. 为什么要用指针

    解决跨区域(不同的作用域 不同代码块)之间的数据交互

    例如通过函数来改变数值:

    //通过指针传给函数地址 来改变变量的值
    //如果使用形式参数则达不到这样的效果
    void test(int *a){
        *a++;
    }
    
    int main(int argc, const char * argv[]) {
        int a = 10;
        int *pa = &a;
        test(pa);
        printf("%d\n",a);
    
    return 0;
    }
    
    

    2. 指针的表现形式

    • '*':

    1.声明/定义变量的时候 表示一个指针变量

            float b = 20;
            int c = 10;
            int *a;   定义一个指针变量 指向的内存空间只能放整数
            注意:定义指针变量的时候画一定要给初值  不确定就给NULL
            int *a = b;不行,指针变量只能存地址 不能存具体值
            int *a = &b;不行,整型指针只能存整形数据的地址
    
             int *a = &c;正确
             float *d = NULL;NULL指向内存的起始地址 0x00
    
    1. 除了定义指针变量之外 都是访问某个 地址的值
         int *temp = &c;  //访问指针变量
         *temp = 21;访问temp地址里面的数据 赋值为21
    
    • '&':

    取某个变量的地址,如最熟悉的scanf函数

    3. 指针的占用内存

    所有的指针类型都占8个字节(64位)

    二、指针的运用

    1. 函数指针

    int test(int a){
        return 0;
    }
    
    int main(int argc, const char * argv[]) {
        
        int(*pFunc)(int)  = test;
    
    return 0;
    }
    

    2. 数组与指针的关系

      数组名并不是一个变量,没有分配内存空间 例如int a = 10;而指针变量是有内存空间的

    int score[5] = {1,2,3,4,5};
        printf("%p\n",score);
        printf("%p\n",&score);
        
        for (int i = 0; i < 5; i++) {
            printf("%d ",*(score + i));
            //加i个元素   score+ i = 0x7ffeefbff510 + i*4
        }
        printf("\n");
        
        printf("%p\n",score);  //0x7ffeefbff510
        printf("%p\n",score+1);  //0x7ffeefbff514
        printf("%d\n",*(score+1)); //2
        printf("%d\n",*score+1); //2
        
        printf("%d\n",(*score)++);  //1
        printf("%d\n",score[0]);    //2
        printf("%d\n",++*score);  //3
    
    

    *(score + i)表示加I个元素,而不是加i个字节

    例如整型数据:

    score+ i = 0x7ffeefbff510 + i**sizeof(int)
    
    • 区别

    定义类型 数组 指针变量
    区别 系统会分配内存空间 可以存值 只为变量本身分配8个字节内存空间 无法存值
    struct Person{
            char name[10];   //字符有对齐 与最近的对齐
            char *address;
            int age;
        };
    
        
        //定义结构体struct Person变量 变量名xw
        int i;
        struct Person xw;
       // xw.name = "小王";   //数组一旦定义 地址不能改变
                         //不能直接给数组赋值
        
        xw.name[0] = 'x';   //系统为这个变量分配内存了
        xw.name[1] = 'w';
        
       xw.address = "西南大学";    //常量字符串地址是由系统分配的
        
        //先为address分配内存
        xw.address = malloc(2 * sizeof(char));
        xw.address[0] = 's';      //字符指针赋值
        xw.address[1] = 'n';
        
        
        xw.age = 30;
        
    //结构体赋值用大括号{}
       int i2 = 10;
       struct Person zs = {"张三",20};
        
        printf("name:%s\n",xw.name);
        printf("address:%s\n",xw.address);
    
    
    • 结构体对齐规则参考链接:

    链接1    链接2  链接3

    3. 给指针指向的区域赋值

    • 指针变量已经指向某块区域
    int a = 10;
    int *pA = &a;  //指向变量a的内存地址
     *pA = 30;
    
    • 指针指向一个数组
        int num[10] = {};
        int *pNum = num;  //指向数组num的首地址
        
        *(pNum + 0) = 20;
        pNum[0] = 20;
    
    • 动态分配内存 malloc realloc free

     注意:
            1. 自己分配的内存空间 必须自己释放
            2. 普通变量的内存是系统分配 所以系统自己释放
            3. 常量字符串地址是由系统分配的
    
    
    char *pName = malloc(3 * sizeof(char));
        //判断分配是否成功
        if (pName == NULL) {
            //分配失败
            exit(EXIT_FAILURE);
        }
    
        pName[0] = 'j';
        pName[1] = 'a';
        pName[2] = 'c';
        
        printf("%s\n",pName);
        
        //当之前分配的内存空间不够了 就需要在之前的基础上重新分配
        //realloc 必须是之前使用melloc分配过的
        //如果是系统分配的内存 不能使用realloc
        //用完了就要自己释放内存
        
        pName = realloc(pName, 4*sizeof(char));
        pName[3] = 'k';
        
        
    //手动释放内存
        free(pName);
    

    4. 单链表

    //定义一个学生的结构体节点
    typedef struct Node{
        char name[10];
        int ID;
        float score;
        
        struct Node *next;     //32个字节
    } Student;
    
    //初始化一个头结点
    void initHeader(Student **pHeader){
        //动态分配内存
        Student *pTemp = malloc(1 * sizeof(Student));
        
        //初始化
        pTemp->next = NULL;
        //改变外部的值
        *pHeader = pTemp;
        
        
    }
    
    

    三、心得体会

      指针这块的知识理解程度还是不够深,要靠平时更多的积累来加深,通过更多的demo练手,灵活运用指针,使代码更加简洁。

    相关文章

      网友评论

          本文标题:C语言指针小结

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