《C语言程序设计第11章指针和数组课件》由会员分享,可在线阅读,更多相关《C语言程序设计第11章指针和数组课件(42页珍藏版)》请在金锄头文库上搜索。
1、第第第第11111111章章章章 指针和数组指针和数组指针和数组指针和数组2024/8/82/42本章学习内容本章学习内容本章学习内容本章学习内容 指针与一维数组间的关系,指针与二维指针与一维数组间的关系,指针与二维数组间的关系数组间的关系 向函数传递一维数组和二维数组向函数传递一维数组和二维数组 指针数组,命令行参数指针数组,命令行参数 动态数组,动态内存分配动态数组,动态内存分配2024/8/83/4211.1 11.1 指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系 intint a4=1,2,3,4; a4=1,2,3,4;0 0x0037b0
2、00x0037b000a0a00 0x0037b004x0037b0040 0x0037b008x0037b0080 0x0037b00Bx0037b00Ba a.1intint * *pa=a;pa=a;papaintint * *pa=&a0;pa=&a0;234a1a1a2a2a3a3数组名是一个常量指针数组名是一个常量指针数组名是一个常量指针数组名是一个常量指针不能修改该指针的指向不能修改该指针的指向不能修改该指针的指向不能修改该指针的指向指针可当数组名使用指针可当数组名使用指针可当数组名使用指针可当数组名使用2024/8/84/4211.1 11.1 指针和一维数组间的关系指针和一维
3、数组间的关系指针和一维数组间的关系指针和一维数组间的关系 intint a4=1,2,3,4; a4=1,2,3,4;0 0x0037b000x0037b000a0a00 0x0037b004x0037b0040 0x0037b008x0037b0080 0x0037b00Bx0037b00Ba a.1intint * *pa=a;pa=a;papaintint * *pa=&a0;pa=&a0;234a1a1a2a2a3a3数组元素的等价引用形式数组元素的等价引用形式数组元素的等价引用形式数组元素的等价引用形式aiai*(a+i)*(a+i)paipai*(pa+i)*(pa+i)a+1a+
4、1*(a+1)*(a+1)pa0pa0*(pa+2)*(pa+2)pa+2pa+2*pa*pa2024/8/85/4211.1 11.1 指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系 intint a4=1,2,3,4; a4=1,2,3,4;0 0x0037b000x0037b000a0a00 0x0037b004x0037b0040 0x0037b008x0037b0080 0x0037b00Bx0037b00Ba a.1p p234a1a1a2a2a3a3for (i=0; i4; i+) scanf(%d, &ai); for (i=0; i
5、4; i+) printf(%d , ai);for (p=a; p(a+4); p+) scanf(%d, p); for (p=a; p(a+4); p+) printf(%d , *p);*p*p*p*pa+4a+42024/8/86/4211.1 11.1 指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系【例例11.111.1】演示数组元素的引用方法演示数组元素的引用方法 2024/8/87/4211.1 11.1 指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系【例例11.111.1】演示数组元素的引用方
6、法演示数组元素的引用方法 2024/8/88/4211.1 11.1 指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系【例例11.211.2】演示数组和指针变量作函数参数演示数组和指针变量作函数参数 被调函数的形参声明为被调函数的形参声明为数组类型,用下标法访数组类型,用下标法访问数组元素问数组元素2024/8/89/4211.1 11.1 指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系【例例11.211.2】演示数组和指针变量作函数参数演示数组和指针变量作函数参数 被调函数的形参声明为被调函数的形参声明为指针指
7、针类型类型,用指针法访,用指针法访问数组元素问数组元素2024/8/810/4211.1 11.1 指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系指针和一维数组间的关系【例例11.211.2】演示数组和指针变量作函数参数演示数组和指针变量作函数参数 在主函数中这样做没有在主函数中这样做没有多大的实际意义多大的实际意义2024/8/811/4211.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系 可将二维数组看作一维数组,其每个数组元素又是可将二维数组看作一维数组,其每个数组元素又是可将二维数组看作一维数组,其每个数组元
8、素又是可将二维数组看作一维数组,其每个数组元素又是一个一维数组一个一维数组一个一维数组一个一维数组 按行顺序存放所有元素按行顺序存放所有元素按行顺序存放所有元素按行顺序存放所有元素a00a01a02a10a11a12a0a0a1a1a0+1a0+2&a0a000&a1a100&a11a1+1&a12&a01&a02 a00 a0a01a02a10 a1 a11a12 a a1+2shortshort a23;a aa a+1+12024/8/812/4211.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系a00a01a02a10a11a1
9、2 a00 a0a01a02a10 a1 a11a12 a shortshort a23;a aa a+1+1a 代表代表二二维数组的首地址,维数组的首地址,第第0 0行行的地址,的地址,行地址行地址行地址行地址a + i 代表代表第第i i行行的地址的地址但并非增加但并非增加i i个字节!个字节!2024/8/813/42a00a01a02a10a11a12a0a0a1a1&a0a000&a1a100 a00 a0a01a02a10 a1 a11a12 a shortshort a23;*(a + i) 即即 ai 代表代表第第i行行第第第第0 0列列列列的地址的地址,列地址列地址列地址列地
10、址a aa a+1+1*(a+i) + j 即即 ai + j代表代表第第i行行第第第第j j列列列列的地址的地址&aij &a12a1+211.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系2024/8/814/42a00a01a02a10a11a12a0a0a1a1&a0a000&a1a100 a00 a0a01a02a10 a1 a11a12 a shortshort a23;a aa a+1+1&a12a1+2* *( *(a+i) + j ) 即即 aij 代表代表第第i行第行第j列列的的内容内容内容内容*(a + i) 即即
11、ai 代表代表第第i行行第第第第0 0列列列列的地址的地址,列地址列地址列地址列地址*(a+i) + j 即即 ai + j代表代表第第i行行第第第第j j列列列列的地址的地址&aij 11.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系2024/8/815/42 二维数组的二维数组的二维数组的二维数组的行行行行指针指针指针指针int int ( (* *p)3;p)3;p = a; p = a; /用行地址初始化用行地址初始化用行地址初始化用行地址初始化 逐行查找逐行查找逐行查找逐行查找- - - -逐列查找逐列查找逐列查找逐列查找ps
12、hortshort a23;a00a01a02a10a11a12a12a aa+1a+111.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系2024/8/816/42 二维数组的二维数组的二维数组的二维数组的行行行行指针指针指针指针int int ( (* *p)3;p)3;p = a; p = a; /用行地址初始化用行地址初始化用行地址初始化用行地址初始化 逐行查找逐行查找逐行查找逐行查找- - - -逐列查找逐列查找逐列查找逐列查找pshortshort a23;a00a01a02a10a11a12a+1a+1a a11.2 11.
13、2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系2024/8/817/42 二维数组的二维数组的二维数组的二维数组的行行行行指针指针指针指针int int ( (* *p)3;p)3;p = a; p = a; /用行地址初始化用行地址初始化用行地址初始化用行地址初始化 逐行查找逐行查找逐行查找逐行查找- - - -逐列查找逐列查找逐列查找逐列查找forfor (i=0; im; i+) (i=0; im; i+)forfor (j=0; jn; j+) (j=0; jn; j+) printf( printf( %d%d , ,*(*(p+i)+j
14、)*(*(p+i)+j););shortshort a23;a00a01a02a10a11a12pa aa+1a+111.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系2024/8/818/42 二维数组的二维数组的二维数组的二维数组的列列列列指针指针指针指针int int * *p;p;p = p = * *a; a; /用列地址初始化用列地址初始化用列地址初始化用列地址初始化 逐个查找逐个查找逐个查找逐个查找相对偏移量相对偏移量相对偏移量相对偏移量forfor (i=0; im; i+) (i=0; im; i+)forfor (j=
15、0; jn; j+) (j=0; jn; j+) printf( printf( %d%d , ,*(p+*(p+i*n+ji*n+j) ););pshortshort a23;a00a01a02a10a11a12*a*a或或或或a0a0pi*n+ji*n+j11.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系2024/8/819/42【例例11.311.3】输入一个输入一个3 3行行4 4列的列的二维数组,然后输出这个二维数组,然后输出这个二维数组的元素值二维数组的元素值 11.2 11.2 指针和二维数组间的关系指针和二维数组间的关系
16、指针和二维数组间的关系指针和二维数组间的关系2024/8/820/42【例例11.311.3】输入一个输入一个3 3行行4 4列的二维数组,然后输列的二维数组,然后输出这个二维数组的元素值出这个二维数组的元素值 11.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系形参声明为列数已知的形参声明为列数已知的二维数组二维数组2024/8/821/42【例例11.311.3】输入一个输入一个3 3行行4 4列的二维数组,然后输列的二维数组,然后输出这个二维数组的元素值出这个二维数组的元素值 11.2 11.2 指针和二维数组间的关系指针和二维数组
17、间的关系指针和二维数组间的关系指针和二维数组间的关系形参声明为指向列数已知形参声明为指向列数已知的二维数组的行指针的二维数组的行指针2024/8/822/42【例例11.311.3】输入一个输入一个3 3行行4 4列的二维数组,然后输列的二维数组,然后输出这个二维数组的元素值出这个二维数组的元素值 11.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系形参声明为指向二维数组形参声明为指向二维数组的列指针的列指针2024/8/823/42【例例11.311.3】输入一个输入一个3 3行行4 4列的二维数组,然后输列的二维数组,然后输出这个二维
18、数组的元素值出这个二维数组的元素值 11.2 11.2 指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系指针和二维数组间的关系2024/8/824/42指针和数组作函数参数指针和数组作函数参数 通过指针或数组参数,使调用者获得修改后的通过指针或数组参数,使调用者获得修改后的通过指针或数组参数,使调用者获得修改后的通过指针或数组参数,使调用者获得修改后的数据数据数据数据 通过一个参数把大量的数据送到函数内通过一个参数把大量的数据送到函数内通过一个参数把大量的数据送到函数内通过一个参数把大量的数据送到函数内如果只向内传送数据,就把参数定义为如果只向内传送数据,就把参数定义为如果只
19、向内传送数据,就把参数定义为如果只向内传送数据,就把参数定义为constconst,防,防,防,防止意外修改数据,也让函数的功能更明确止意外修改数据,也让函数的功能更明确止意外修改数据,也让函数的功能更明确止意外修改数据,也让函数的功能更明确 voidvoid PrintArray( PrintArray(constconst int *int *p, p, intint n) n) . voidvoid PrintArray( PrintArray(constconst intint a, a, intint n) n) . 2024/8/825/42指针、数组以及其他的类型混合指针、数组以
20、及其他的类型混合指针、数组以及其他的类型混合指针、数组以及其他的类型混合 基本数据类型基本数据类型基本数据类型基本数据类型intint、longlong、charchar、shortshort、floatfloat、doubledouble 数组是一种数据类型数组是一种数据类型数组是一种数据类型数组是一种数据类型是从其他类型派生的类型是从其他类型派生的类型是从其他类型派生的类型是从其他类型派生的类型 每个元素都有一个类型每个元素都有一个类型每个元素都有一个类型每个元素都有一个类型 指针是一种数据类型指针是一种数据类型指针是一种数据类型指针是一种数据类型是从其他类型派生的类型是从其他类型派生的类
21、型是从其他类型派生的类型是从其他类型派生的类型 XXXXXXXX类型的指针类型的指针类型的指针类型的指针 任何类型都可以作指针或者数组的任何类型都可以作指针或者数组的任何类型都可以作指针或者数组的任何类型都可以作指针或者数组的基类型基类型基类型基类型2024/8/826/4211.311.3指针数组及其应用指针数组及其应用指针数组及其应用指针数组及其应用 用指针作数组的基类型用指针作数组的基类型用指针作数组的基类型用指针作数组的基类型? 指针数组指针数组指针数组指针数组(Pointer ArrayPointer ArrayPointer ArrayPointer Array)元素均为指针类型数
22、据的数组元素均为指针类型数据的数组元素均为指针类型数据的数组元素均为指针类型数据的数组 定义形式为:定义形式为:定义形式为:定义形式为: 数据类型数据类型数据类型数据类型 * * * *数组名数组名数组名数组名 数组长度数组长度数组长度数组长度; 例如例如例如例如char *char *ptr5;ptr5; ptrptr55* *charchar2024/8/827/42第第第第1010章章章章【例例例例10.410.4】国名国名国名国名字符串排序字符串排序字符串排序字符串排序二维数组二维数组二维数组二维数组charchar namenameNNMAX_LENMAX_LEN; ; .forfo
23、r (i=0; in-1; i+) (i=0; in-1; i+) forfor (j = i+1; jn; j+) (j = i+1; jn; j+) ifif( (strcmp(strj,stri)0strcmp(strj,stri)0) ) strcpy(temp,stri); strcpy(temp,stri); strcpy(stri,strj);strcpy(stri,strj); strcpy(strj,temp);strcpy(strj,temp); MAX_LENMAX_LENN N交换字符数组中的字符串交换字符数组中的字符串物理排序物理排序2024/8/828/42【例例例
24、例11.411.4】国名国名国名国名字符串排序字符串排序字符串排序字符串排序指针数组指针数组指针数组指针数组charchar *ptrN;*ptrN;.forfor (i=0; in-1; i+) (i=0; in-1; i+) forfor (j = i+1; jn; j+) (j = i+1; jn; j+) ifif( (strcmp(ptrj,ptri)0strcmp(ptrj,ptri)1)(x1)为指向每个参数的字符指针为指向每个参数的字符指针为指向每个参数的字符指针为指向每个参数的字符指针2024/8/832/42【例例例例11.511.5】演示命令行参数与演示命令行参数与演示命
25、令行参数与演示命令行参数与mainmain函数各形参之间的关系函数各形参之间的关系函数各形参之间的关系函数各形参之间的关系 intint main(int argc, char *argv) main(int argc, char *argv) intint i; i; printf(The number of command line arguments is:%dn,argc); printf(The number of command line arguments is:%dn,argc);printf(The program name is:%sn, argv0);printf(The
26、 program name is:%sn, argv0);ifif (argc 1) (argc 1) printf(The other arguments are following:n);printf(The other arguments are following:n);forfor (i = 1; i (i = 1; i 1) (argc 1) printf(The other arguments are following:n);printf(The other arguments are following:n);forfor (i = 1; i (i = 1; iargcarg
27、c; i+); i+) printf(%sn, printf(%sn, argviargvi);); return 0; return 0; The number of command line arguments is: 4The program name is: echo.exeThe other arguments are following: programming is fun2024/8/834/4211.4.1 C11.4.1 C程序的内存映像程序的内存映像程序的内存映像程序的内存映像 C C程序中变量的内存分配方式程序中变量的内存分配方式 从静态存储区分配从静态存储区分配从静态
28、存储区分配从静态存储区分配全局变量和静态变量全局变量和静态变量 在栈上创建在栈上创建在栈上创建在栈上创建 存放函数参数值、局部变量值等存放函数参数值、局部变量值等在执行函数调用时,系统在栈上为函数内的局部变量及形在执行函数调用时,系统在栈上为函数内的局部变量及形参分配内存,函数执行结束时,自动释放这些内存参分配内存,函数执行结束时,自动释放这些内存从堆上分配从堆上分配从堆上分配从堆上分配 在程序运行期间,用动态内存分配函数来申请的内存都是在程序运行期间,用动态内存分配函数来申请的内存都是从堆上分配的,动态内存的生存期由程序员自己来决定从堆上分配的,动态内存的生存期由程序员自己来决定 2024/
29、8/835/4211.4.2动态内存分配函数动态内存分配函数Two primary methods of allocating memory:void*void* malloc(unsigned int size);void*void* calloc(unsigned int num, unsigned int size);# #includeinclude # #includeinclude void*void*类型的指针可以指向任意类型的变类型的指针可以指向任意类型的变量,通常强转量,通常强转(Type*)(Type*)为其他类型为其他类型2024/8/836/4211.4.2动态内存分配
30、函数动态内存分配函数Two primary methods of allocating memory:void* malloc(unsigned int size);void* calloc(unsigned int num, unsigned int size);向系统申请大小为向系统申请大小为sizesize的内存块的内存块把首地址返回,若申请不成功则返回把首地址返回,若申请不成功则返回NULLNULL向系统申请向系统申请num个个size大小的内存块大小的内存块把首地址返回,若申请不成功则返回把首地址返回,若申请不成功则返回NULL2024/8/837/4211.4.2动态内存分配函数动
31、态内存分配函数voidvoid* * free(free(voidvoid* p);* p);释放由释放由malloc()和和calloc()申请的内存块申请的内存块p是指向此块内存的指针是指向此块内存的指针free时系统标记此块内存为未占用,可被重新分配时系统标记此块内存为未占用,可被重新分配Method of deallocating memory:2024/8/838/42p pn n确保指针使用前是非空指针确保指针使用前是非空指针释放向系统申请的存储空间释放向系统申请的存储空间 11.4.311.4.3【例例例例11.611.6】一维动态数组一维动态数组一维动态数组一维动态数组2024
32、/8/839/42p pn n像使用一维数组一样像使用一维数组一样使用动态数组使用动态数组11.4.311.4.3【例例例例11.611.6】一维动态数组一维动态数组一维动态数组一维动态数组2024/8/840/42确保指针使用前是确保指针使用前是非空指针非空指针释放向系统申请的释放向系统申请的存储空间存储空间 p pm*nm*n11.4.411.4.4【例例例例11.711.7】二维动态数组二维动态数组二维动态数组二维动态数组2024/8/841/42仍当作一维数组仍当作一维数组来使用来使用 p pm*nm*n11.4.411.4.4【例例例例11.711.7】二维动态数组二维动态数组二维动态数组二维动态数组2024/8/842/42Questions and answers