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

    地址

    注: 把指针比喻成门牌号,信封邮寄地址,现在我看到指针就想起门牌号,信封地址

    #include "stdio.h"
    
    int main()
    {
        int a = 10;
        int *p = &a;
        printf("%p
    ", p);
        return 0;  
    }
    
    // output
    0x7fff5fbff81c

     分析:是系统 RAM 中的特定位置,通常以十六进制的数字表示,系统通过这个地址,就可以找到相应的内容,当使用80386时,我们必须区分以下三种不同的地址:逻辑地址,线性地址,物理地址;在进行C语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址(偏移地址),不和绝对物理地址相干,比如上面那个"0x7fff8b6a378c" 就是逻辑地址。逻辑地址不是被直接送到内存总线,而是被送到内存管理单元(MMU)。MMU由一个或一组芯片组成,其功能是把逻辑地址映射为物理地址,即进行地址转换。下面是转换关系图:

     指针

    一、指针变量的定义

    指针:一个变量的指针就是该变量的地址(地址就是指针)

    指针变量:存放变量地址的变量,他是用来指向另一个变量

    1. 格式:变量类型 *指针变量名;

    2. 举例:int *p;   char *p2;

    3. 注意:定义变量时的*仅仅是指针变量的象征

    二、利用指针变量简单修改其他变量的值

    1.指向某个变量

    int a;

    int *p;

    p = &a;

    或者

    int *p = &a;

    2.修改所指向变量的值

    *p = 10;

    3.在函数内部修改外面变量的值

    int a = 10;
    change(&a);
    
    void change(int *n)
    {
        *n = 20;
    }
    

     4.指针使用注意:

    int main()
    {

    /* 不建议的写法, int *p只能指向int类型的数据 int *p; double d = 10.0; p = &d;*/ /* 指针变量只能存储地址 int *p; p = 200; */ /* 指针变量未经过初始化,不要拿来间接访问其他存储空间 int *p; printf("%d ", *p); */ int a = 10; /* int a; a = 10; */ /* int *p; p = &a; */ // 定义变量时的*仅仅是一个象征,没有其他特殊含义 int *p = &a; // 不正确的写法 // *p = &a; p = &a; // 这个时候的*的作用:访问指向变量p指向的存储空间 *p = 20; char c = 'A'; char *cp = &c; *cp = 'D'; printf("%c ", c);
    return 0;
    }
    // output
    D

     练习小结:

    #include <stdio.h>
    void swap(int *v1, int *v2);
    
    int main()
    {
        /*
        int a = 10;
        int b = 11;
        
        swap(&a, &b);
        */
        
        
        int a2 = 90;
        int b2 = 89;
        
        swap(&a2, &b2);
        
        printf("a2=%d, b2=%d
    ", a2, b2);
        return 0;
    }
    
    /* 不能交换外面实参的值,仅仅是交换了内部指针的指向
    void swap(int *v1, int *v2)
    {
        int *temp;
        temp = v1;
        v1 = v2;
        v2 = temp;
    }*/
    
    // 完成两个整型变量值的互换
    void swap(int *v1, int *v2)
    {
        int temp = *v1;
        *v1 = *v2;
        *v2 = temp;
    }
    
    /* 交换的只是内部v1、v2的值
    void swap(int v1, int v2)
    {
        int temp = v1;
        v1 = v2;
        v2 = temp;
    }*/
    

     指针疑问:/*

     %d int
     %f floatdouble
     %ld long
     %lld long long
     %c char
     %s 字符串
     %zd  unsigned long
     */
    
    #include <stdio.h>
    
    /*
     0000 0001
     0000 0010
     0000 0000
     0000 0000
     
     0000 0000 0000 0000 0000 0010 0000 0001
     */
    
    int main()
    {
        // 0000 0000 0000 0000 0000 0000 0000 0010
        int i = 2;
        // 0000 0001
        char c = 1;
        
        char *p;
        p = &c;
        
        //*p = 10;
        
        printf("c的值是%d
    ", *p);
        
        return 0;
    }
    
    void test()
    {
        char c; // 1
        int a; // 4
        long b; // 8
        
        // 任何指针都占用8个字节的存储空间
        char *cp;
        int *ap;
        long *bp;
        
        printf("cp=%zd, ap=%zd, bp=%zd
    ",
               sizeof(cp),
               sizeof(ap),
               sizeof(bp));
    }

    三、指针与数组

    1.将数组当做函数参数传入时,会自动转为指针

    /*
     1.数组元素的访问方式
     int ages[5];
     int *p;
     p = ages;
     1> 数组名[下标]  ages[i]
     2> 指针变量名[下标] p[i]
     3> *(p + i)
     
     2.指针变量+1,地址值究竟加多少,取决于指针的类型
      int *   4
      char *  1
      double * 8
     */
    void change(int array[]);
    
    int main()
    {
        // 20个字节
        int ages[5] = {10, 11, 19, 78, 67};
        
        change(ages);
        
        return 0;
    }
    
    // 利用一个指针来接收一个数组,指针变量array指向了数组的首元素
    void change(int *array)
    {
        printf("%d
    ", array[2]);
        //printf("%d
    ", *(array+2));
    }
    
    /*
    void change(int array[])
    {
        int s = sizeof(array);
        
        printf("%d
    ", s);
    }*/
    
    void test()
    {
        double d = 10.8;
        double *dp;
        dp = &d;
        
        printf("dp = %p
    ", dp);
        printf("dp + 1 = %p
    ", dp + 1);
        
        int ages[5] = {10, 9, 8, 67, 56};
        
        int *p;
        // 指针变量p指向了数组的首元素
        p = &ages[0];
        // 数组名就是数组的地址,也是数组首元素的地址
        //p = ages;
        
        /*
         p ---> &ages[0]
         p + 1 ---> &ages[1]
         p + 2 ---> &ages[2]
         p + i ---> &ages[i]
         */
        
        //printf("%d
    ",  *(p+2));
        
        printf("%d
    ",  p[2]);
        
        /*
         for (int i = 0; i<5; i++) {
         printf("ages[%d] = %d
    ", i, *(p+i));
         }*/
        
        
        //    printf("%p
    ", p);
        //    printf("%p
    ", p + 1);
        //    printf("%p
    ", p + 2);
    }
    

    四. 指针与字符串

    1.常量区

     存放一些常量字符串

     2.堆

     对象

     3.栈

     存放局部变量

    掌握:

     定义字符串的2种方式

     1> 利用数组

     char name[] = "itcast";

      * 特点:字符串里面的字符是可以修改的

      * 使用场合:字符串的内容需要经常修改

     2> 利用指针

      char *name = "itcast";

      * 特点:字符串其实是一个常量字符串,里面的字符是不能修改

      * 使用场合:字符串的内容不需要修改,而且这个字符串经常使用

    int main()
    {
        char name[20];
        
        printf("请输入姓名:
    ");
        
        scanf("%s", name);
        
        // 'j' 'a' 'c' 'k' ''
        
        //printf("%c
    ", name[3]);
        
        //printf("刚才输入的字符串是:%s
    ", name);
        
        return 0;
    }
    
    // 定义字符串数组
    void test2()
    {
        char *name = "jack";
        
        //int ages[5];
        
        // 指针数组(字符串数组)
        char *names[5] = {"jack", "rose", "jake"};
        
        // 二维字符数组(字符串数组)
        char names2[2][10] = {"jack", "rose"};
    }
    
    // 定义字符串
    void test()
    {
        // 字符串变量
        char name[] = "it";
        name[0] = 'T';
        
        //printf("%s
    ", name);
        
        
        // "it" == 'i' + 't' + ''
        // 指针变量name2指向了字符串的首字符
        
        // 字符串常量
        char *name2 = "it";
        
        char *name3 = "it";
        
        //*name2 = 'T';
        
        //printf("%c
    ", *name2);
        
        printf("%p
    %p
    ", name2, name3);
        
        //printf("%s
    ", name2);
    }
    
  • 相关阅读:
    十、CI框架之通过参数的办法输出URI路径
    九、CI框架之将URI转为数组原型
    八、CI框架之输出URI路径,相当于GET
    七、CI框架之分配变量数组,循环输出
    六、CI框架之分配变量
    五、CI框架之通过带路径的view视图路径访问
    四、CI框架之通过URL路径访问C中的函数
    三、CI框架之一个最简单的页面
    二、CI框架之MCV模型
    一、CI框架(CodeIgniter)简介
  • 原文地址:https://www.cnblogs.com/dj123456/p/4762607.html
Copyright © 2011-2022 走看看