为什么要使用指针?

  • 指针为函数提供借助形参修改实参的手段
  • 指针为动态内存分配提供支持
  • 指针为动态数据结构(链表,队列等)提供支持
  • 指针使程序更高效,简洁

    地址和指针的概念

  • 堆空间内存无法命名,只能通过地址来访问

  • 指针:一个变量的地址称为该变量的“指针”。如&x为变量x的指针。

    • 指针的本质是内存地址。
    • 内存地址:内存单元的编号。
    • 所谓变量的地址一般均指首地址(即变量所占内存单元中第一个单元的地址)。
    • 专门用于存放其量他变地址的变量称为指针变量。

      变量的指针和指向变量的指针变量

  • 指针变量:专门存放地址的变量;

  • 变量的指针:就是变量的地址;
  • 怎样定义指针变量?
    • 基本类型标识符 * 指针变量名;
  • 定义指针变量要注意几点:
    • 1、指针变量名前“” 只表示该变量为指针变量,以便区别于普通变量的定义,而指针变量名不包含该“”;
      • 例如:int s; 说明s是一个指针变量,但不能说s是指针变量;
    • 2、定义指针变量时必须指明基类型。一个指针变量不能忽而指向整形,忽而又指向实型。因为。不同类型的变量所占的字节数是不同的。
    • 3、与一般的变量一样,也可以对指针变量进行初始化。
  • 指针变量的操作:
    • 1、给指针变量赋值。如:
      • p= &a;
        • 注意指针变量的类型要与指向的变量的类型一致;
    • 2、获取指针变量的值(a的地址)。如
      • printf(“%p”,p);
    • 3、获取指针变量指向的变量(a的值)。如
      • printf(“%d”,*p);
    • 注意:
      • 利用指针变量访问内存中的数据,一次访问的内存单元大小,取决于指针变量的类型:
        • char p ——> p 访问 p指向的内存空间一个字节的数据;
        • int p ——-> p 访问p指向的内存空间四个字节的数据;
      • 指针变量所占的内存单元,不取决于指针变量的类型;取决于操作系统,32位操作系统,占有4个字节,64位操作系统,占有8个字节
    • 指针变量作为函数参数:
      • 输出型参数;指针变量可以作为输出型参数。

        通过指针引用数组

        通过指针引用字符串

        指向函数的指针

  • 返回指针值的函数(指针函数)
    • 返回指针值的函数
      • 类型标识符 *函数名(形参列表)
      • {函数体}
  • 指针数组和多重指针
    • 元素类型为指针类型数据的数组称为指针数组。也就是说,指针数组中的每一个元素都相当于一个指针变量。
    • 指针数组和数组指针:
      • 指针数组:
        • 例子: int * p[8]; //定义了具有8个元素的指针数组,每个元素都是一个整型指针变量。
      • 数组指针:
        • 例子 int (*p)[8];//定义了一个指针变量,指针变量指向具有8个整型元素的数组。
    • 多级指针:存放指针变量地址的 指针变量;
      • 二级指针应用:
        • main 主函数的参数;
        • main函数的完整格式:
          • int main(int argc,char **argv);
          • int main (int argc,char * argv[]);
            • 参数:argc : 获取命令行参数个数
              • C语言指针(2021.5.28) - 图1
            • 引申问题:
              • 字符串转数值:atoi sscanf
              • 数值转字符串 sprintf
    • 指针常量,常量指针
  • 动态内存分配与指向它的指针变量
    • 动态内存分配拟是通过系统提供的库函数来实现的,主要有以下4个函数:
      • malloc 函数 void *malloc(unsigned int size);
        • 作用: 在内存的动态存储区中分配一个长度为size(字节)的连续空间。
        • 说明: 此函数的返回值是所分配区域的 起始地址,即指针值。
      • calloc 函数 void *calloc(unsigned int n,unsigned int size);
        • 作用:在内存的动态存储区中分配n个长度为size的连续空间。
        • 说明: 说明 此函数可以为一维数组开辟动态存储空间,n 为数组元素个数,为个元素长度为size,这就是动态数组。
      • realloc函数 void realloc(void p,unsigned int size);
        • 作用:将p指向的临时分配域的大小改变为size大小。
        • 说明 : 若想改变已经通过malloc函数或calloc函数分配的临时域的大小,可以用recalloc函数重分配。
      • 释放:free 函数 void free(void *p);
        • 作用 :释放由指针变量p指向的动态空间,使这部分空间能被其它变量使用。
        • 说明 : p是最近一次调用callo或malloc函数时的返回值。该函数无返回值。
  • 内存操作
    • C语言对内存的操作是通过系统提供的库函数来实现的,主要有以下4个函数:
      • 1.内存清零
        • memset 函数 void memset(void s, int c, size_t n);
          • 作用 : 用c去填充起始地址为s的内存前size个字节连续空间。
          • 说明 : 此函数的返回值是s的地址。
            • 例如: char a[10]; memset(a,0,10);
            • 功能:开辟10字节的临时存储空间,将该空间内全部填充为0。
      • 2.内存拷贝
        • memcpy函数 void memcpy(void dest, const void *src, size_t n);
          • 作用 将内存地址src 的前n个字节的数据拷贝到内存地址dest。
          • 说明 此函数适合于内存地址无重叠的拷贝。
      • 3.内存移动
        • memmove函数 void memmoe (void dest, const void *src, size_t n);
          • 作用 : 将内存地址src 的前n个字节的数据拷贝到内存地址dest。
          • 说明 : 此函数可用于内存地址重叠的拷贝。
      • 4.内存比较
        • memcmp函数 int memcmp(const void s1, const void s2, size_t n);
          • 作用: 比较存地址s1和s2 的前n个字节的数据
          • 说明 :若参数s1 和s2 所指的内存内容都完全相同则返回0 值。s1 若大于s2 则返回大于0 的值。s1 若小于s2 则返回小于0 的值。
      • 5.内存查找
        • void memchr( const void * dest,int c ,unsigned int size);
    • 理解: void * 未指明类型的指针变量;
      • 使用过程中,需要强制类型转换为需要的指针类型;