1、指针指针的重要性表示一些复杂的数据结构快速传递数据使函数返回一个以上的值能直接访问硬件能方便处理字符串是理解面向对象语言中引用的基础总结:指针是 C 语言的灵魂指针的定义地址内存单元的编号从零开始的非负整数范围:4G指针1.指针就是地址,地址就是指针2.指针变量是存放地址的变量3.指针和指针变量是两个不同的概念4.叙述时通常把指针变量简称为指针,实际它们含义不一样5.指针的本质就是一个操作受限的非负整数指针的分类基本类型指针(重要)#includeInt f(int i,int j)return 100;/ return 88;errorInt main (void) Int a=3,b=5;
2、a=f(a,b);b=f(a,b);只能返回一个值# include Void g(int*p,int*q)*p=1;*q=2;Int main(void) Int a=3,b=5;g(Printf(“%d%dn”,a,b);Return 0;指针使函数返回一个以上的值int main(void)int *p; /p 是变量的名字,int*表示 p 变量存放的是 int 类型变量的地址Int*p;不表示定义了一个名字叫做*p 的变量Int*p;应该理解为:p 是变量名,p 变量的数据类型是 int*类型所谓 int*类型,实际就是存放 int 变量地址的类型int i=3;char ch=Ap
3、= /OK1.p 保存了 i 的地址,因此 p 指向 i2.p 不是 i,i 也不是 p,修改 p 的值不影响 i 的值,修改 i 的值也不影响 p 的值3.如果一个指针变量指向了某个普通变量,则*指针变量 完全等同于 普通变量例:若 p 指向 i,则*p=i (*p 和 i 可互相替换 )p=/error/p=i; /error,因为类型不一致,p 只能存放 int 类型变量的地址,不能存放 int 类型变量/P=55;/error,原因同上return 0; 附注: *的含义:1.乘法2.定义指针变量Int*p; /定义了一个名字叫做 p 的变量,int*表示 p 只能存放 int 变量的
4、地址3.指针运算符该运算符放在已经定义好的指针变量的前面如果 p 是一个已经定义好的指针变量则*p 表示以 p 的内容为地址的变量如何通过被调函数修改主调函数普通变量的值1.实参必须为该普通变量的地址 t=a;a=b;b=t;return;int main(void)int a=3;int b=5;huhuan(a,b);printf(“a=%d,b=%d/n”,a,b);return 0;a=3,b=5Press any key to continue互换失败#includevoid huhuan2(int *p, int *q)int *t;/如果要互换 p 和 q 的值,则 t 必须是
5、int*,不能是 intt=p;p=q;q=t;return;int main(void)int a=3;int b=5;huhuan2( /*huhuan2(*p,*q);是错误的huhuan2(a,b);也是错误的*/printf(“a=%d,b=%dn”,a,b);return 0;a=3,b=5Press any key to continue互换失败#includevoid huhuan3(int *p, int*q)/形参的名字是 p 和 q,接收实参数据的是 p 和 q,而不是*p 和*qint t;/如果要互换 *p 和*q 的值,则 t 必须是 int,不能是 int*t=*
6、p;/p 是 int*,*p 是 int*p=*q;*q=t;return;int main(void)int a=3;int b=5;huhuan3(/*huhuan3(*p,*q)是错误的huhuan3(a,b)也是错误的*/printf(“a=%d,b=%d/n”,a,b);return 0;a=5,b=3Press any key to continue互换成功形参和实参是不同的变量,修改形参不会改变实参指针常见错误#includeInt main(void)Int i=5;Int*p;Int*q;P=/*q=p;/error 语法编译会出错/*q=*p;/errorP=q;/q 是垃
7、圾值, q 赋给 p,p 也是垃圾值printf(“%dn”,*q); /13 行/*q 的空间是属于本程序的,所以本程序可以读写 q 的内容,但是如果 q 内部是垃圾值,则本程序不能读写*q 的内容因为此时*q 所代表的内存单元的控制限权并没有分配给本程序所以本程序运行到 13 行时就会立即出错*/return 0;指针和数组指针和一维数组一维数组名一维数组名是个指针常量它存放的是一维数组第一个元素的地址下标和指针的关系如果 p 是个指针变量,则 pi永远等价于*(p+i)确定一个一维数组需要几个参数(如果一个函数要处理一个一维数组,则需要接收该数组的哪些信息)需要两个参数:数组第一个元素的
8、地址数组的长度# include/f 函数可以输出任何一个一维数组的内容void f(int * pArr, int len)int i;for(i=0,ivoid f(int * pArr,int len) pArr3=88; /10 行int main(void)int a6=1,2,3,4,5,6printf(“%dn”,a3); /17 行f(a,6);printf(“%dn”,a3); /19 行 若写为/pArr2=*( pArr+2)=*(a+2)=a2Int main(void)int a6=1,2,3,4,5,6printf(“%dn”,a2); f(a,5);printf(
9、“%dn”,a2); /a=/error 因为 a 是常量/printf(“%#X,%#Xn”,a,/a=310Press any key to continue# includeVoid OutArr(int*pArr,int len)Int i;For(i=0;iInt main(void) int i=5;Int j=10;Int*p=Int*q=/p-q 没有实际意义Return 0;#includeInt main(void) int i=5;Int j=10;Int*p=Int*q=Int a5;p=q=Printf(“p 和 q 所指向的单元相隔%d 个单元n”,q-p);p 和
10、 q 所指向的单元相隔 3 个单元Press any key to continuesizeof(变量名)功能:返回值是该变量所占的字节数假设 p 指向 char 类型变量(1 个字节)假设 q 指向 int 类型变量(4 个字节)假设 r 指向 double 类型变量(8 个字节)指针和二维数组指针和函数指针和结构体多级指针#includeInt main(void) char ch=A;Int i=99;Double x=66.6Char * p=Int *q=Double * r=Printf(“%d%d%dn”,sizeof(p),sizeof(q),sizeof(r)Return 0;4 4 4 Press any key to continue专题:动态内存分配(重难点)传统数组的缺点:1.数组长度必须事先制定,且只能是常整数,不能是变量。例子:int a5; /OKInt len=5; int alen;/errorInt a5.6;/error2.传统形式定义的数组,该数组的内存程序员无法手动释放为什么需要动态分布内存动态内存分配举例-动态数组的构造静态内存和动态内存的比较跨函数使用内存的问题