为什么要使用指针?
- 指针为函数提供借助形参修改实参的手段
- 指针为动态内存分配提供支持
- 指针为动态数据结构(链表,队列等)提供支持
-
地址和指针的概念
堆空间内存无法命名,只能通过地址来访问
指针:一个变量的地址称为该变量的“指针”。如&x为变量x的指针。
指针变量:专门存放地址的变量;
- 变量的指针:就是变量的地址;
- 怎样定义指针变量?
- 基本类型标识符 * 指针变量名;
- 基本类型标识符 * 指针变量名;
- 定义指针变量要注意几点:
- 1、指针变量名前“” 只表示该变量为指针变量,以便区别于普通变量的定义,而指针变量名不包含该“”;
- 例如:int s; 说明s是一个指针变量,但不能说s是指针变量;
- 例如:int s; 说明s是一个指针变量,但不能说s是指针变量;
- 2、定义指针变量时必须指明基类型。一个指针变量不能忽而指向整形,忽而又指向实型。因为。不同类型的变量所占的字节数是不同的。
- 3、与一般的变量一样,也可以对指针变量进行初始化。
- 1、指针变量名前“” 只表示该变量为指针变量,以便区别于普通变量的定义,而指针变量名不包含该“”;
- 指针变量的操作:
- 1、给指针变量赋值。如:
- p= &a;
- 注意指针变量的类型要与指向的变量的类型一致;
- 注意指针变量的类型要与指向的变量的类型一致;
- p= &a;
- 2、获取指针变量的值(a的地址)。如
- printf(“%p”,p);
- printf(“%p”,p);
- 3、获取指针变量指向的变量(a的值)。如
- printf(“%d”,*p);
- printf(“%d”,*p);
- 注意:
- 利用指针变量访问内存中的数据,一次访问的内存单元大小,取决于指针变量的类型:
- char p ——> p 访问 p指向的内存空间一个字节的数据;
- int p ——-> p 访问p指向的内存空间四个字节的数据;
- char p ——> p 访问 p指向的内存空间一个字节的数据;
- 指针变量所占的内存单元,不取决于指针变量的类型;取决于操作系统,32位操作系统,占有4个字节,64位操作系统,占有8个字节
- 利用指针变量访问内存中的数据,一次访问的内存单元大小,取决于指针变量的类型:
- 指针变量作为函数参数:
- 1、给指针变量赋值。如:
- 返回指针值的函数(指针函数)
- 返回指针值的函数
- 类型标识符 *函数名(形参列表)
- {函数体}
- 类型标识符 *函数名(形参列表)
- 返回指针值的函数
- 指针数组和多重指针
- 元素类型为指针类型数据的数组称为指针数组。也就是说,指针数组中的每一个元素都相当于一个指针变量。
- 指针数组和数组指针:
- 指针数组:
- 例子: int * p[8]; //定义了具有8个元素的指针数组,每个元素都是一个整型指针变量。
- 例子: int * p[8]; //定义了具有8个元素的指针数组,每个元素都是一个整型指针变量。
- 数组指针:
- 例子 int (*p)[8];//定义了一个指针变量,指针变量指向具有8个整型元素的数组。
- 例子 int (*p)[8];//定义了一个指针变量,指针变量指向具有8个整型元素的数组。
- 指针数组:
- 多级指针:存放指针变量地址的 指针变量;
- 二级指针应用:
- main 主函数的参数;
- main函数的完整格式:
- int main(int argc,char **argv);
- int main (int argc,char * argv[]);
- 参数:argc : 获取命令行参数个数
- 引申问题:
- 字符串转数值:atoi sscanf
- 数值转字符串 sprintf
- 字符串转数值:atoi sscanf
- 参数:argc : 获取命令行参数个数
- int main(int argc,char **argv);
- main 主函数的参数;
- 二级指针应用:
- 指针常量,常量指针
- 元素类型为指针类型数据的数组称为指针数组。也就是说,指针数组中的每一个元素都相当于一个指针变量。
- 动态内存分配与指向它的指针变量
- 动态内存分配拟是通过系统提供的库函数来实现的,主要有以下4个函数:
- malloc 函数 void *malloc(unsigned int size);
- 作用: 在内存的动态存储区中分配一个长度为size(字节)的连续空间。
- 说明: 此函数的返回值是所分配区域的 起始地址,即指针值。
- 作用: 在内存的动态存储区中分配一个长度为size(字节)的连续空间。
- calloc 函数 void *calloc(unsigned int n,unsigned int size);
- 作用:在内存的动态存储区中分配n个长度为size的连续空间。
- 说明: 说明 此函数可以为一维数组开辟动态存储空间,n 为数组元素个数,为个元素长度为size,这就是动态数组。
- 作用:在内存的动态存储区中分配n个长度为size的连续空间。
- realloc函数 void realloc(void p,unsigned int size);
- 作用:将p指向的临时分配域的大小改变为size大小。
- 说明 : 若想改变已经通过malloc函数或calloc函数分配的临时域的大小,可以用recalloc函数重分配。
- 作用:将p指向的临时分配域的大小改变为size大小。
- 释放:free 函数 void free(void *p);
- 作用 :释放由指针变量p指向的动态空间,使这部分空间能被其它变量使用。
- 说明 : p是最近一次调用callo或malloc函数时的返回值。该函数无返回值。
- 作用 :释放由指针变量p指向的动态空间,使这部分空间能被其它变量使用。
- malloc 函数 void *malloc(unsigned int size);
- 动态内存分配拟是通过系统提供的库函数来实现的,主要有以下4个函数:
- 内存操作
- 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。
- 例如: char a[10]; memset(a,0,10);
- 作用 : 用c去填充起始地址为s的内存前size个字节连续空间。
- memset 函数 void memset(void s, int c, size_t n);
- 2.内存拷贝
- memcpy函数 void memcpy(void dest, const void *src, size_t n);
- 作用 将内存地址src 的前n个字节的数据拷贝到内存地址dest。
- 说明 此函数适合于内存地址无重叠的拷贝。
- 作用 将内存地址src 的前n个字节的数据拷贝到内存地址dest。
- memcpy函数 void memcpy(void dest, const void *src, size_t n);
- 3.内存移动
- memmove函数 void memmoe (void dest, const void *src, size_t n);
- 作用 : 将内存地址src 的前n个字节的数据拷贝到内存地址dest。
- 说明 : 此函数可用于内存地址重叠的拷贝。
- 作用 : 将内存地址src 的前n个字节的数据拷贝到内存地址dest。
- memmove函数 void memmoe (void dest, const void *src, size_t n);
- 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 的值。
- 作用: 比较存地址s1和s2 的前n个字节的数据
- memcmp函数 int memcmp(const void s1, const void s2, size_t n);
- 5.内存查找
- void memchr( const void * dest,int c ,unsigned int size);
- void memchr( const void * dest,int c ,unsigned int size);
- 1.内存清零
- 理解: void * 未指明类型的指针变量;
- 使用过程中,需要强制类型转换为需要的指针类型;
- 使用过程中,需要强制类型转换为需要的指针类型;
- C语言对内存的操作是通过系统提供的库函数来实现的,主要有以下4个函数:

