zoukankan      html  css  js  c++  java
  • 指针 (C语言)

    指针

     

        指针的概念: 内存的地址编号(类似房间门牌号)

         int a = 10; 

        通过代码查看a的指针(地址编号)

        &: 取地址运算符

        &a: 返回变量a的首地址

        %p: 用于打印指针, 16进制

         printf("a的地址: %p ", &a); 

        指针变量: 用户存放指针(地址)的变量

        定义的格式

        数据类型 *变量名 = 初值

        定义一个整型指针变量 

      int *p = NULL;//*代表定义的是指针变量
    
        printf("%p
    ", p);
    
        p = &a;
    
        printf("%p
    ", p);

        指针变量的作用

        直接访问: 通过变量名获取内存中的值

        printf("%d ", a); 

        间接访问: 通过内存地址编号, 找到内容, 再获取内存中的值

     printf("%d", *p);//*: 取值运算符
    
        */
    
        /*
    
        int a = 15, b = 10;
    
        int *x = &a;
    
        int *y = &b;
    
        x = y;
    
        *x = 20;
    
        printf("a = %d, b = %d
    ", a, b);
    
        */
    
        /*
    
         int a = 15, b = 20;
    
         int *x = &a;
    
         int *y = &b;
    
         *x = 11;
    
         int *p = &a;
    
         p = y;
    
         *y = 21;
    
         printf("a = %d, b = %d
    ", a, b);
    
         printf("%d %d %d", *x, *y, *p);
    
        */
    
        /*
    
        int a = 6, b = 8, c = 10;
    
        int *x = &a;
    
        x = &c;
    
        int *y = &b;
    
        int *z = &c;
    
        *z = 5;
    
        *x = 12;
    
        x = y;
    
        *y = *x + *z;
    
        printf("a = %d, b = %d c = %d
    ", a, b, c);
    
        printf("%d %d %d
    ", *x, *y, *z);
    
        */

        *: 代表定义的是指针变量

        &: 取地址运算符

     int *p1 = &a;//定义指针变量p1, 存a的首地址

     int *p2 = &b;//定义指针变量p2, 存b的首地址

    p1 = p2;//把指针变量变量p2的值赋给指针变量p1 

        *: 取值运算符

         printf("%d ", *p1);//取出p1指向内存中的数据 

    指针常见的问题

        1.内存地址比较低的内存单元, 有系统控制, 不允许访问

          int *p = NULL; //*p = 10;//error 

       2.野指针, 定义指针变量时, 没有赋初值, 指向不定

          int *p;

       //*p = 100;//error 

        3.定义指针变量, *属于谁?

     int *p1 = NULL;//推荐, int * 是p1的类型

    int* p2 = NULL;

    int*p3 = NULL;

    int * p4 = NULL; 

       4.指针变量所占的字节数

        a.与数据类型无关

        b.与操作系统的位数相关, 64位占8个字节, 32位占4个字节

        int *p = NULL;
        printf("%lu
    ", sizeof(p));//8
        printf("%lu
    ", sizeof(int *));
        printf("%lu
    ", sizeof(char *));
        printf("%lu
    ", sizeof(short *));
        printf("%lu
    ", sizeof(long *));
        printf("%lu
    ", sizeof(float *));
        printf("%lu
    ", sizeof(double *));
        printf("%lu
    ", sizeof(bool *));

        5.定义指针变量的数据类型有什么作用

        a.指针变量的数据类型, 决定了*(取值运算符)取多少个字节的内容

        int a = 260;
    
        int *p = &a;
    
        printf("%d
    ", *p);
    
        char c = 'a';
    
        char *p1 = &c;
    
        printf("%c
    ", *p1);

       b.定义指针变量的数据类型, 决定了指针变量+1操作时, 跳转多少个字节

        long *p = NULL;
    
        printf("%p
    ", p);//0x0
    
        printf("%p
    ", p + 1);//0x8
    
        printf("%p
    ", ++p);//0x8
    
        printf("%p
    ", p);//0x8
    
        printf("%p
    ", p++);//0x8
    
        printf("%p
    ", p);//0x10

        指针的应用

        指针在数组中的使用

        1.数组在内存中是连续存储的

         int array[5] = {1, 2, 3, 4, 5}; 

       第一个元素的地址, 就是数组的首地址

         printf("%p ", &array[0]); 

        2.数组的名字就是数组的首地址

     printf("%p
    ", array);
    
        for (int i = 0; i < 5; i++) {
    
    //        printf("%d ", array[i]);
    
              printf("%d ", *(array + i));
    
        }
    
        //a[b] = *(a + b)
    
        //b[a] = *(b + a)
    
        //a[b] = b[a]
    
        printf("
    ");
    
        for (int i = 0; i < 5; i++) {
    
            printf("%d ", i[array]);
    
        }
    
        printf("
    ");

    10个元素的整形数组, 随机赋值, [22, 66]

    int a[10] = {0};
    
        for (int i = 0; i < 10; i++) {
    
            *(a + i) = arc4random() % (66 - 22 + 1) + 22;
    
            printf("%d ", *(a + i));
    
        }
    
        printf("
    ");

    冒泡排序    

    for (int i = 0; i < 9; i++) {
    
            for (int j = 0; j < 9 - i; j++) {
    
                if (*(a + j) > *(a + j + 1)) {
    
                    int temp = *(a + j);
    
                    *(a + j) = *(a + j + 1);
    
                    *(a + j + 1) = temp;
    
                }
    
            }
    
        }
    
        
    
        for (int i = 0; i < 10; i++) {
    
            printf("%d ", *(a + i));
    
        }
    
        printf("
    ");

    数组元素

        a[0]      *a

        a[1]      *(a + 1)

        ...       ...

        a[n -1]   *(a + n - 1)

        

     元素的首地址

        &a[0]     a

        &a[1]     a + 1

        ...       ...

        &a[n - 1] a + n - 1 

        int a[5] = {1, 2, 3, 4, 5};
    
        printf("%d
    ", a[1]);
    
        printf("%d
    ", *(a + 1));

      定义一个指针变量存数组的首地址

        int *p = a;
    
        printf("%d
    ", p[1]);
    
        printf("%d
    ", *(p + 1));

    数组名a(数组首地址) 指向数组首地址的指针变量p

       相同点

       所有数组可以执行的操作, 指向数组首地址的指针变量p, 也都可以执行

       不同点

       1.数组名(数组首地址)是一个常量地址, 不能修改; 指针变量可以重新指向

         int number = 10;

       p = &number; //a = &number;//error 

       2.使用sizeof, 如果是数组名(数组首地址), 计算的是数组所占的字节数; 如果是指针变量, 计算的是指针变量所占的字节数   

        printf("%lu
    ", sizeof(a));//20
     
        printf("%lu
    ", sizeof(p));//8

    指针在字符串中的使用

       字符数组

        字符串

        字符串数组

         char string[10] = "jiujing"; 

        %s打印的实质: 从给定地址开始, 依次打印字符, 直到遇到''结束

         printf("%s ", string); printf("%s ", string + 4); 

        char string[] = "I love you!";
    
        *(string + 1) = '';
    
        *(string + 7) = '';
    
        printf("%s
    ", string);
    
        printf("%s
    ", string + 3);
    
        printf("%s
    ", string + 7);
    
        printf("%s
    ", string + 8);

    计算字符串的长度, 不使用strlen

     char str[] = "Do one thing at a time, and do well";
    
        int i = 0;
    
        while(*(str + i) != ''){
    
            i++;
    
        }
    
        printf("长度: %d
    ", i);

     

     

    The one who wants to wear a crown must bear the weight!
  • 相关阅读:
    Luogu P2633 Count on a tree
    Luogu P4011 孤岛营救问题
    Luogu P3157 [CQOI2011]动态逆序对
    SCOI2015 国旗计划
    AT2165 Median Pyramid Hard
    BZOJ2959 长跑
    SCOI2015 情报传递
    SDOI2011 染色
    SCOI2010 幸运数字
    SHOI2016 黑暗前的幻想乡
  • 原文地址:https://www.cnblogs.com/OrangesChen/p/4827129.html
Copyright © 2011-2022 走看看