1 / 21

C 语言程序设计

C 语言程序设计. 同学们好!下面开始讲授 C 语言课程的第 10 讲内容。   第 10 讲 指针( 2 )   四、指针与数组   五、动态存储分配   六、使用指针和动态存储分配的程序举例 四、指针与数组 1. 指针与一维数组   ( 1 )一维数组名是指向该数组第一个元素的指针常量 int a[7]={12,25,18,30,63,44,50};   * a 表示 a[0] 元素,* a 的值即为 a[0] 的值。 a 的值等于 &a[0] ,类型 int* 。. 第 10 讲 指针( 2 ) 四、指针与数组 五、动态存储分配

Download Presentation

C 语言程序设计

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C语言程序设计 同学们好!下面开始讲授C语言课程的第10讲内容。   第10讲 指针(2)   四、指针与数组   五、动态存储分配   六、使用指针和动态存储分配的程序举例 四、指针与数组 1. 指针与一维数组   (1)一维数组名是指向该数组第一个元素的指针常量 int a[7]={12,25,18,30,63,44,50};   *a表示a[0]元素,*a的值即为a[0]的值。 a的值等于&a[0],类型int*。 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  2. C语言程序设计 a为指针常量,即其值不可修改,所以使用a++是错误的。道理很简单,如果允许修改数组名的值,以后就无法访问该数组了。    (2)数组元素的下标和指针访问方式 a[i]等价于*(a+i),分别为下标和指针访问方式。   *a与a[0],*(a+1)与a[1]等价。   假定int *p=a+i; 则 *p与a[i],*p++与a[i++]等价。 for (i=0; i<7; i++) printf("%5d\n",a[i]);//下标方式   等价于:for (i=0; i<7; i++) printf("%5d\n",*(a+i));//指针方式   等价于:for (p=a; p<a+7; p++) printf("%5d\n",*p);//指针方式   等价于:for (p=a,i=0; i<7; i++) printf("%5d\n",p[i]);//下标方式 //p初始指向数组a中第1个元素,p[i]与a[i]等价,均为*(a+i) 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  3. C语言程序设计 2. 指针与二维数组   (1)二维数组名是指向该数组第一行元素的指针常量,其值为整个二维数组空间的首地址 int b[3][4]={{1,2,3,4},{2,4,6,8},{3,6,9,12}}; b为指向b[0]行4个元素的指针常量,其值为&b[0],亦即&b[0][0]的值,但类型为int(*)[4],而不是int*。 b[i]为i行元素(一维数组)的数组名,b[i]的值为b[i][0]元素的地址。它们的类型均为int*,即b[i]+1指向i行行首下一元素。   而&b[i]的值虽然也等于b[i][0]元素的地址,但类型为int(*)[4],因为它是该行元素的首地址,即b[i+1]指向i+1行行首元素 。注意b[i]+1与b[i+1]的区别,b[i]+1为指向i行行首的下一个元素指针,即指向b[i][1];而b[i+1]则为指向i的下一行行首元素的指针,即指向b[i+1][0] 。   同一维数组名一样,不允许修改二维数组名的值,如进行b++操作是错误的。 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  4. C语言程序设计   (2)二维数组名的值可以赋给同类型的指针变量 int (*pb)[4]=b;//把b的值赋给同类型的指针变量pb,pb也指向此数组,//此后pb也可以作为数组名使用,访问任何元素 pb[2][3]等价与b[2][3],值为12。   注意:int (*pb)[4]与int (*pb)[5]不同,因为pb所指向的元素个数不同。    若int *pb[4]则定义pb为含有4个元素的整型指针数组,而不是定义指向含有4个整型元素的数组的指针。   二维数组元素的下标和指针访问方式 b[i][j](*(b+i))[j] 或*(b[i]+j) 或*(*(b+i)+j)//均等价 for (i=0; i<3; i++) { for (j=0; j<4; j++) printf("%d ", b[i][j]);// *(*(b+i)+j) 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  5. C语言程序设计 printf("\n"); }   (3)使用指针和数组的程序举例  例1: #include<stdio.h> void main() { int a[8]={3,5,7,9,11,13,15,17}; int i,*p=a;//p的值为&a[0] for (i=0;i<8;i++) { printf("%5d ",*p++);//先*p,后p的值加1 if ((i+1)%4==0) printf("\n");//输出4个元素后换行 } }   输出结果: 3579 11131517 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  6. C语言程序设计 例2: #include<stdio.h>   void main()   { int a[8]={46,38,72,55,24,63,50,37};   int max=*a, min=*a;    //a[0]的值赋给max和min int *p;   for(p=a+1; p<a+8; p++) {  //扫描整个数组 if(*p>max) max=*p;   //大放max   if(*p<min) min=*p;   //小放min   } printf("%5d %5d\n", max,min); //输出最大和最小值   }   输出结果:72 24 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  7. C语言程序设计 五、动态存储分配 1. 动态存储分配的概念   变量和数组在计算机内存中都有对应的存储空间,该存储空间的分配时机有两种:一种在编译阶段,或者说在程序运行前;另一种在程序运行之中。前者称为静态存储分配方式,后者称为动态存储分配方式。   (1)变量的静态存储分配方式   通过一般的变量定义语句定义的变量,采用的是静态存储分配方式。如: int x,y; //x和y分别对应的4个字节的存储空间是静态分配的 int a[10];//数组a所需要的40个字节的存储空间是静态分配的 char b[20],*p=b;//数组b的20个字节和指针变量p的4字节是静态分配的 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  8. C语言程序设计 double c[M][N]={{0}}; //数组c的M*N*8个字节的存储空间是静态分配的   (2)变量的动态存储分配方式   变量的动态存储分配需要调用在系统头文件stdlib.h中声明的动态存储分配函数来实现,这些函数为malloc()、calloc()和realloc()三种。 2. 动态存储分配函数的原型格式和功能   (1)malloc()函数原型格式 void * malloc(unsigned int k);   功能:调用它时能够分配k个字节的存储空间,并把第1个字节的地址返回,该返回值具有void*类型,可以赋给任一具体类型的指针变量。 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  9. C语言程序设计   (2)calloc()函数原型格式 void * calloc(unsigned int n, unsigned int k);   功能:调用它时能够分配n*k个字节的存储空间,并把第1个字节的地址返回,该返回值具有void*类型,可以赋给任一具体类型的指针变量。通常用n表示数组长度,k表示元素类型的长度。   (3)realloc()函数原型格式 void * realloc(void* ptr, unsigned int k);   功能: 调用它时能够分配k个字节的存储空间,接着把ptr已经指向的动态分配的存储空间的内容复制到新分配的存储空间中,最后把新分配的存储空间的第1个字节的地址返回。由于该返回值具有void*类型,所以能够赋给任一具体类型的指针变量,通常仍赋给ptr所对应的实参指针变量,使得通过该调用后增加或缩小动态存储空间。 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  10. C语言程序设计 3. 动态存储分配的调用格式举例   (1)int *px=malloc(sizeof(int)); //分配一个整数存储空间由指针变量px所指向,此动态分配的变量为*px,可用它保存一个整数,如:*px=25; *px+=30; //其值为55   (2)double *pa=calloc(10,sizeof(double)); //分配一个具有10个双精度元素的一维数组空间,由指针变量pa所指向,pa也就是该动态数组的数组名(但有区别,它是变量不是常量) //通过它可以访问该数组中的任何元素。如:*pa=12; 把12赋给 // pa[0]元素;又如:pa[i]<pa[j]进行两元素大小的比较 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  11. C语言程序设计   (3)pa=realloc(pa,20*sizeof(double)); //增加pa指针所指向的存储空间的大小,由10个双精度元素变为 //20个双精度元素,同时原有的存储内容被复制过来。   (4)int **top=calloc(M+1,sizeof(int*)); //top动态数组含有M+1个元素,每个元素能够存储一个整数的地址。 4. 动态存储分配的优点   允许在程序运行过程中随时确定待使用的存储空间的大小,不必像静态分配那样需要事先确定。   一般定义一个数组时,必须确切给出数组的每一维的尺寸,如: int a[10], b[M][N]; //M和N必须是已经定义的符号常量 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  12. C语言程序设计 动态分配定义一个数组时,所分配的存储空间的大小可以是常量,也可以是变量。如:   (1)int *a=calloc(10,4); //两个参数都为常量   (2)int *a=calloc(x,4); //第1个参数为变量,分配x个整数元素的空间   (3)char *b=malloc(n1+n2); //n1和n2为变量,分配n1+n2个字节的空间   (4)char *c=malloc(sizeof(d)); //根据另一个对象d的大小分配空间   5. 动态存储空间的释放   释放动态存储空间的free()函数的原型格式   void free(void* ptr);   功能:调用它时能够把指针变量ptr所指向的动态存储空间释放掉,即归还给操作系统。 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  13. C语言程序设计 free()函数原型声明也包含在stdlib.h系统头文件中。   当动态存储空间保存的内容不再使用时,可调用该free()函数及时释放掉,若没有调用它,则一直到程序运行结束时该动态存储空间才被自动释放给操作系统。   对于一般静态分配的变量,其占有的存储空间只能由C语言系统在运行时自动释放,其时机为所在的模块(复合语句)刚执行完毕。   下面看一个程序例子   #include<stdio.h>  //支持调用标准输入和输出操作的函数   #include<stdlib.h>  //支持调用动态存储分配和释放函数   void main()   {   int *a=calloc(10,sizeof(int)); //动态分配得到a[10]数组, //为40字节的存储空间,同时静态分配得到a指针变量,4字节 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  14. C语言程序设计 int i;    //静态分配得到i整数变量,4字节   for(i=0; i<10; i++) a[i]=i*i; //给a数组中每个元素赋值   for(i=0; i<10; i++) printf("%d ",a[i]); //输出a中每个元素值   printf("\n"); //输出一个换行符   free(a); //a[10]数组的40个字节的动态存储空间被交还给操作系统   } //此主函数执行结束时,自动把a和i各占有的4字节交还给操作系统   程序运行结果:   0 1 4 9 16 25 36 49 64 81 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  15. C语言程序设计 六、使用指针和动态存储分配的程序举例   例1:以指针方式访问数组元素的例子   #include<stdio.h>   #include<stdlib.h>   void main() {   int a[5]={3,6,9,12,15}; int *p=a;  //把数组a的首地址赋给指针变量p   int i; for(i=0;i<5;i++) printf("%5d",*p++); //指针方式访问数组a   printf("\n");  //换行 for(p=a+4; p>=a; p--) printf("%5d",*p);  //从后向前访问数组元素   printf("\n");  //换行   } 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  16. C语言程序设计   输出结果: 3691215 1512963   例2:进行简单变量动态存储分配的例子 #include<stdio.h> #include<stdlib.h> void main() { int x=23,y=40,z; int *p1=malloc(sizeof(int));//为*p1动态分配4字节存储空间 int *p2=malloc(sizeof(int));//为*p2动态分配4字节存储空间 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  17. C语言程序设计   *p1=x; *p2=y;//分别把x值23和y值40赋给动态变量*p1和*p2 printf("%d %d\n",*p1,*p2);//输出*p1和*p2的值为23 40 z=*p1; *p1=*p2; *p2=z;//交换*p1和*p2所保存的值 printf("%d %d\n",*p1,*p2);//输出*p1和*p2的值为40 23 free(p1); free(p2);//释放p1和p2各自所指向的动态存储空间 }   程序运行结果: 23 40 40 23   例3:动态存储分配任意大小的一维数组的例子 #include<stdio.h> #include<stdlib.h> void main() 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  18. C语言程序设计 int *a,i,sum,n; printf("从键盘给n输入一个正整数(1-10): "); while(1) { scanf("%d",&n); //输入1-10之间的数到n中 if(n>=1 && n<=10) break; else printf("重输: "); }   a=calloc(n,sizeof(int)); //动态分配a[n]数组空间,n是变量 a[0]=0; a[1]=1;     //给a数组的前2个元素赋值   for(i=2; i<n; i++) a[i]=a[i-1]+a[i-2]; //从元素a[2]起,每个元素值等于前2个元素值之和   //0+1=1, 1+1=2, 1+2=3, 2+3=5,… for(i=0; i<n; i++) { sum+=a[i];   //计算出n个元素之和   printf("%5d",a[i]); //依次输出每个元素值 } 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  19. C语言程序设计 printf("\n sum=%5d\n", sum);//输出sum的提示信息和值 free(a); }   程序运行结果:   从键盘给n输入一个正整数(1-10): 12   重输: 8 011235813 sum = 33   例4: 动态存储分配二维数组的例子。 #include<stdio.h> #include<stdlib.h> void main() { int i,j; int row,col; 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  20. C语言程序设计 int** ab;//定义2阶整型指针变量ab,用它指向int*类型的数据 printf("输入一个二维表格数据的行数和列数: "); scanf("%d %d", &row, &col);//输入行、列数到row和col中 ab=calloc(row, sizeof(int*));//得到动态分配的一维指针数组ab[row] for (i=0; i<row; i++)//依次使ab[i]指向包含col个元素的一维数组 ab[i]=calloc(col, sizeof(int)); printf("输入%d行*%d列的二维表格数据:\n", row, col); for (i=0; i<row; i++)//输入数据进入二维数组ab[row][col]中 for (j=0; j<col; j++) scanf("%d",&ab[i][j]);//等价表示: *(ab[i]+j) 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

  21. C语言程序设计 printf("\n"); printf("输出二维表格数据: \n"); for (i=0; i<row; i++) {//按row行和col列输出数据 for (j=0; j<col; j++) printf("%5d",ab[i][j]); printf("\n"); } for (i=0; i<row; i++) free(ab[i]);//释放每个一维数组空间 free(ab);//释放ab所指向的一维数组空间 }   总结:第9、10讲  指针: 指针的概念、变量、运算、指针与数组、动态存储分配   这一讲就到这里,同学们再见! 第10讲 指针(2) 四、指针与数组 五、动态存储分配 六、使用指针和动态存储分配的程序举例

More Related