美文网首页
C语言基础之指针(一)

C语言基础之指针(一)

作者: Eugene_iOS | 来源:发表于2023-03-28 16:09 被阅读0次

    C语言基础之指针(一)
    C语言基础之指针(二)

    1、内存那些事儿

    物理内存:计算机设备中的存储固件

    虚拟内存:操作系统虚拟出来的内存,当一个进程被创建或者程序运行的时候都会分配虚拟内存;由操作系统实现物理内存虚拟内存之间的映射。

    虚拟内分配机制:内存(线性空间),以字节为单位,每字节都会有独一无二的地址,地址呈线性增长。数据在内存中是以大、小端字节序的方式存储。

    • 基本数据类型(int、short):以小端或大断方式存储。
    • 数组类型:在内存中会为数组分配一块连续的内存空间,按顺序存储。(数组中的基本数据类型,根据小端或大端存储,而数组元素按顺序存储)

    注意:在32位系统下,每个进程的寻址范围是4G,0x00 00 00 00 ~ 0xff ff ff ff。
    了解更多动态内存DRAM和静态内存SRAM

    2、指针

    指针就是地址(虚拟内存中的地址)。

    3、指针变量

    是个变量,用来存放一个地址编号,该地址编号是其它数据单元(变量/数组/结构体/函数等)的首地址。若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元,若指针存放的值是0,则这个指针为空指针。

    4、指针大小

    在32位系统下,所有类型的指针都是4个字节

    5、指针和变量的关系

    在程序中,引用变量的方法

    1. 直接通过变量的名称
      int a;
      a = 100;
    2. 也可以通过指针变量
      int *p; // 定义一个指针变量,*修饰p是个指针变量
      p = &a; // 取的地址给 p赋值,p保存了a的地址,也可说p指向了a
      *p = 100;// 在调用的时候*是取值的意思,*指针变量 等价于 指针指向的变量


    6、指针的运算

    6.1、指针可以加一个整数,往上指几个它指向的变量,结果还是个地址

    int array[] = "hello";
    int *point = array;// c语言规定:数组名数组的首地址,此时point指向数组的首地址,也是第 0 个元素的地址
    point += 1;// 移动指针地址(最终移动的字节数和指针变量的类型有关)
    printf("point = %p\n",point);// 输出结果为数组元素‘e’的地址(和大小端有关也存在一定关系)

    6.2、两个相同类型指针可以比较大小

    前提:只有两个相同类型的指针指向同一个数组元素的时候,比较大小才有意义;指向前面元素的指针小于指向后面元素的指针;

    6.3、两个相同类型的指针可以做减法

    前提:必须是两个相同类型的指针指向同一个数组的元素的时候,做减法才有意义;做减法的结果是,两个指针指向的中间有多少个元素。

    6.4、两个相同类型的指针可以相互赋值

    注意:
    1、只有相同类型的指针才可以相互赋值(void *类型的除外)。
    2、如果类型不同的指针想要互相赋值,必须进行强制类型转换。

    6.5、指针操作方式总结

    指针操作方式:取地址取内容等。

    7、指针 和 数组的关系

    1、指针可以保存数组元素的地址
    2、可以定义一个数组,数组中有若干个相同类型的指针变量,这个数组被称为指针数组

    8、指针数组

    指针数组:本身是个数组,是指针数组,是若干个相同类型的指针变量构成的集合。其数组名即为指向该数据类型的指针,数组的定义等效于申请内存、定义指针和初始化。
    例1:(申请内存、定义指针和初始化)
    char a[ ] = {0x33, 0x34, 0x35};
    等效于:

    • 申请内存;
    • 定义 char *a = 0x4000;
    • 初始化数组;

    例2:(利用下标引用数组数据也等效于指针取内容.)

    • a[0]; 等效于 *a;
    • a[1]; 等效于 *(a+1);
    • a[2]; 等效于 *(a+2);


    9、指针的指针:即指针的地址

    int a; // 定义一个变量a
    int *p;// 定义一个指针变量p,即一级指针,保存普通变量的地址(指针变量本身占4个字节)
    p = &a;// 将 普通变量a的地址 赋值给 指针变量p
    此时:*p == a


    int **pp;// 定义一个指针的指针变量pp (二级指针:保存一级指针的地址)
    pp = &p;// 将 指针变量p 赋值给 指针的指针变量pp
    此时:
    *pp == p
    *(*pp) == *p == a


    int ***ppp;// 定义一个三级指针(三级指针:保存二级指针)
    ppp = &pp;
    此时:*(*(*ppp)) == a
    ⚠️注意:p、pp、ppp都是指针变量,都占4个字节,都存放地址编号,只是类型不同

    10、指针和字符串

    字符串:以\0结尾的若干字符的集合。
    字符串的存储形式数组字符串指针

    1. char string[100] = "Hello world!";
      定义并初始化字符数组string,来存储"Hello world!"字符集合,该字符集合是存储在string这个变量中的。可动态修改字符串内容。

    2. char *string = "Hello world!";
      定义并初始化一个指针变量string,因为char只占一个字节,只能存放字符地址编号,所以"Hello world!"字符集合不能存放在string指针变量中。此时这里string指针变量只是存放了字符‘H’的地址编号,"Hello world!"字符集合存放在内存的文字常量区。不可动态修改字符串内容。

    3. char *string = (char *)malloc(13 * sizeof(char));
      strcpy(string, "Hello world!")
      动态申请 13(12个字符 + 1个\0结尾字符) 个字节的存储空间,将首地址赋值给指针变量string。最后将字符串"Hello world!"拷贝到string指向的内存空间。可动态修改字符串内容。

    拓展
    char *string = "Hello world!";
    字符数组:在内存(栈、静态全局区)中开辟了一段空间存放字符串。
    字符串指针:在文字常量区开辟了一段空间存放字符串,将字符串的首地址赋值给字符指针。
    :使用malloc函数在堆区申请空间,将字符串拷贝到堆区
    创建操作局部变量时,可使用字符数组;创建使用全局变量时,可在堆区申请内存使用,堆区内存要手动申请、手动释放;

    ⚠️ 注意:字符串的可修改性
    1、栈和全局区中的内存是可以修改的。
    2、文字常量区的内存是不可修改的。
    3、堆区的内容是可以修改的

    相关文章

      网友评论

          本文标题:C语言基础之指针(一)

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