9、指针
利用指针变量可以表示各种数据结构;能很方便地使用数组和字符串;能动态地分配内存;能得到多个函数返回值;并能像汇编语言一样处理内存地址,从而编写出精练而高效的程序。
1、指针与指针变量的概念
1、指针实际上就是内存地址。一个指针变量的值就是某个内存单元的地址(或指针)。一个指针是一个地址,是一个常 量。指针变量是指取值为地址的变量。定义指针的目的是为了通过指针去访问内存单元。
2、内存中每个内存单元也有其大小,一个内存单元如果能存放一个字节的数据,则称为字节存储单元,如果能存放一个字 的数据,则称为字存储单元。
3、分清内存单元的地址与内存单元中的数据。
2、指针变量的定义和引用
1、通过变量名来引用变量的内存单元值的方法被称为直接引用;而通过内存地址引用内存单元值的方法成为间接引用。
2、定义指针变量时,号和变量名是一个逻辑整体。如果一个变量是指针,那么变量名前面一定要有号。*号与变量名之间 可加若干空格。
3、普通变量一定有其数据类型,指针变量也是变量,但它本身并无数据类型,数据类型是指它所指向内存单元的数据类型
4、指针变量使用之前不仅要定义说明,而且必须赋予具体的值。指针变量的赋值只能赋予地址。
5、不允许直接把一个数赋值给指针变量(0除外)。
6、标准C下不能用auto变量的地址去初始化static型指针(但C++可以)。
7、指针变量的值为0的指针称为零指针(空指针)。int *p=0;int *p=NULL;
8、void *类型指针表示不指定p是指向哪一种数据的指针变量,使用时要进行强制类型转换。
9、在指针变量说明中,“*”是类型说明符,表示其后的变量是指针类型,而表达式中出现的 “ * ”则是一个运算符用以表示 指针变量所指的变量。
10、没有赋值的指针变量是没有任何意义的,也绝对是不允许使用的。
11、指针变量也是变量,在内存中也要占用一定的内存单元,但所有类型的指针变量都占用同样大小的内存单元,如VC和 CB下均占4字节。
3、指针和地址运算
1、地址是一种无符号的整数。但不能像整数那样参与乘法和除法。
2、两个指针相加没有任何意义。两个指针相减可表示两指针之间所相差的内存单元数或元素个数。
4、指针与数组
1、数组的指针其实就是数组在内存中的起始地址。
2、数组名是地址常量,不可对其赋值。
3、指向多维数组的指针——数组指针
- 数据类型符 (* 行指针变量名)[常量表达式]
4、元素为指针的数组——指针数组
- 数据类型符 *变量名[常量表达式]
5、指针与字符串
1、字符串的本质其实就是以‘\0’结尾的字符型数组。字符串在内存中的起始地址(即第一个字符的地址)成为字符串的指 针。
2、如果一个指针没有指向一个有效内存就被引用,则被称为“野指针”操作或空指针赋值。
6、指针与动态内存分配
1、当程序中定义变量或数组以后,系统就会给变量或数组按照其数据类型及大小来分配相应的内存单元,这种内存分配的 方式称为静态内存分配。
2、void *malloc(unsigned int size);
- 此函数用于分配若干字节的内存空间,返回一个指向该存储区地址的指针;若系统不能提供足够的内存单元,函数将返回空指针(NULL)。
- malloc前面必须加上一个指针类型转换符,如(int *)。因为malloc的返回值是空类型的指针,一般应与左边的指针变量类型一致。
- 在动态内存分配的语句的后面一般紧跟一条if语句以判断分配是否成功。
3、void *calloc(unsigned int num,unsigned int size);
- 此函数用于给若干个同一类型的数据项分配连续的存储空间,其中每个数据项的长度单位为字节。
- 通过此函数所分配的存储单元,系统将其自动置初值0。
4、void *realloc(void *p,unsigned int size);
- 此函数用于改变原来分配的存储空间的大小。
5、需要动态分配内存的程序一定要坚持“好借好还,再借不难”的原则,在动态内存使用完后,实时释放内存。
- void free(void *block);
6、调用上述函数要包含stdlib.h或malloc.h。
7、多级指针
8、指针作为函数参数
1、常态有两种含义:一是指形参指针本身是常态,一是指形参指针所指向的内存单元是常态。
9、指针作为函数的返回值——指针函数
1、函数类型 *函数名([形参1, 形参2,…])
2、如果一个函数返回一个指针,不能返回auto型局部变量的地址,但可以返回static型变量的地址。
3、返回的指针所对应的内存空间不能因该指针函数的返回而被释放掉。
10、指向函数的指针——函数指针
1、函数类型 (*函数名)([形参1, 形参2,…])
11、带参数的main函数
1、int main(int argc,char *argv[]){} argc用于存放命令行中参数的个数(字符串的个数);argv是一字符型指针数组。
易错:
1、数组名只是个地址,而指针是一个左值。数组做形参传递的是首地址。
2、数组不能由函数组成,即数组元素不能是一个函数;函数也不能返回一个数组或返回另一个函数。