第十一章 指针和数组
1 由于数组名代表数组元素的连续存储空间的首地址,因此,数组元素既可以用下标法也可以用指针来引用。
例11.1见文末
2 p+1与p++在本质上是两个不同的操作,前者不改变当前指针的指向(因为没有进行赋值操作),而后者相当于执行p=p+sizeof(p的基类型),因此改变了p指针的指向,指向下一个元素。
3 p++不是将指针变量加1字节,而是加上1*sizeof(基类型)个字节。
4 输入p和a都是表示首地址,但是数组名a是一个指针常量,不可以进行增1或减1操作,而指针p是一个指针变量,可以这种操作。
5 用一维数组作函数形参与指针变量作函数形参在本质上都是一样的,因此在被调函数中既能以下标形式也能以指针形式访问元素。
例11.2见文末
1 如数组:int a[M][N] 可在逻辑上看成一个M行N列的存储空间。
2 可将二维数组看成由多个元素组成的一维数组,因此可以通过行地址和列地址定位到每个具体的元素。
3 类似于行地址和列地址,可以用行指针和列指针来定位具体元素。
例11.3见文末
1 指针数组是值由若干个基类型相同的指针组成的数组。定义形式为:
类型关键字 *指针数组名[数量];
2 指针数组可以用存储多个字符串。
例11.4见文末
3 指针数组的元素是一个指针,因此与指针变量一样,在使用指针数组前必须对数组元素进行初始化。
4 指针数组可用于表示命令行参数。
例11.5见文末
1 一个编译后的C程序会获得4块在逻辑上不相同并且用于不同目的的内存储区。
2 从低端起,第一块内存为只读存储区,用于存放程序的机器代码和字符串字面量等只读数据。
3 第一块内存相邻的一块是静态存储区,用于存放程序中的全局变量和静态变量等。
4 其他两块内存分别称为堆和栈,属于动态存储区。
5 栈用于保存函数调用时的返回地址、函数的形参、局部变量及CPU的当前状态等程序的运行信息;堆是一个自由存储区,程序可以用C的动态分配函数来使用堆。
6 变量的内存分配可以通过:(1)从静态存储区分配;(2)在栈上分配;(3)在堆上分配。
7 指针的另外一个作用是通过与动态内存分配函数联用,使动态数组成为可能。
8 动态内存分配是指程序运行时为变量分配内存的一种方法,在堆上实现。需要添加头文件
9 函数malloc()用于分配若干字节的内存空间,返回一个指向该内存首地址的指针。如果系统不能提供足够的内存单元,函数则会返回一个空指针NULL。
10 malloc()函数的使用举例:
pi=(int *)malloc(sizeof(int));
表明向系统申请一个大小为4字节的内存,并且pi为int型指针。
11 函数calloc()可用于给若干同一类型的数据项分配连续的存储空间并赋值为0,因此calloc()比malloc()更安全。
12 函数free()的功能是释放向系统动态申请的由指针p指向的存储空间。该函数的形参只能是由malloc()或calloc()申请内存时返回的地址。
13 函数realloc()用于改变原来分配的存储空间的大小。
例11.6见文末
14 永远不要忘记用free()释放不再使用的动态申请的内存。
例11.7见文末
演示数组元素的引用方法,下标法
- //例11.1a 演示数组元素的引用方法,下标法
- #include
- int main(void)
- {
- int a[5],i;
- printf("Input five numbers:");
- for(i=0;i<5;i++)
- {
- scanf("%d",&a[i]);
- }
- for(i=0;i<5;i++)
- {
- printf("%4d",a[i]);//通过数组下标,一个个将元素打印出来
- }
- printf("\n");
- return 0;
- }
演示数组元素的引用方法,解引用
- //例11.1b 演示数组元素的引用方法,解引用
- #include
- int main(void)
- {
- int a[5],i;
- printf("Input five numbers:");
- for(i=0;i<5;i++)
- {
- scanf("%d",a+i);//a+i等价于&a[i]
- }
- for(i=0;i<5;i++)
- {
- printf("%4d",*(a+i));//等价于a[i]
- }
- printf("\n");//这种方法是效率最高的
- return 0;
- }
演示数组元素的引用方法,用移动指针变量p的方法
演示数组元素的引用方法,用移动指针结合下标的方法
- //例11.1d 演示数组元素的引用方法,用移动指针结合下标的方法
- #include
- int main(void)
- {
- int a[5],*p=NULL,i;//需要初始化指针
- printf("Input five numbers:");
- p=a;//等价于p=&a[0];
- for(i=0;i<5;i++)
- {
- scanf("%d",&p[i]);//指针法输入
- }
- for(i=0;i<5;i++)
- {
- printf("%4d",p[i]);//指针法输出
- }
- printf("\n");
- return 0;
- }
主函数a 演示数组和指针变量作为函数参数,实现与例11.1相同的功能
- //例11.2 主函数a 演示数组和指针变量作为函数参数,实现与例11.1相同的功能
- #include
- int main(void)
- {
- int a[5];
- printf("Input five numbers:");
- InputArray(a,5);//数组名作函数参数
- OutputArray(a,5);
- return 0;
- }
主函数b(实际意义不大) 演示数组和指针变量作为函数参数,实现与例11.1相同的功能
- //例11.2 主函数b(实际意义不大) 演示数组和指针变量作为函数参数,实现与例11.1相同的功能
- #include
- int main(void)
- {
- int a[5];
- int *p=a;
- printf("Input five numbers:");
- InputArray(p,5);//指针作函数参数
- OutputArray(p,5);
- return 0;
- }
- //被调函数实现方法一:形参和访问都用数组
- void InputArray(int a[],int n);
- void OutputArray(int a[],int n);
- void InputArray(int a[],int n)//数组作形参
- {
- int i;
- for(i=0;i
- {
- scanf("%d",&a[i]);//下标法访问
- }
- }
- void OutputArray(int a[],int n)
- {
- int i;
- for(i=0;i
- {
- printf("%4d",a[i]);//下标法访问
- }
- printf("\n");
- }
- //被调函数实现方法二:形参和访问都用指针
- void InputArray(int *pa,int n);
- void OutputArray(int *pa,int n);
- void InputArray(int *pa,int n)//指针作形参
- {
- int i;
- for(i=0;i
//这里指针也需移动 - {
- scanf("%d",pa);//指针访问
- }
- }
- void OutputArray(int *pa,int n)
- {
- int i;
- for(i=0;i
- {
- printf("%4d",*pa);//下标法访问
- }
- printf("\n");
- }
- //被调函数实现方法三:形参为数组类型,访问用指针法
- void InputArray(int a[],int n);
- void OutputArray(int a[],int n);
- void InputArray(int a[],int n)//指针作形参
- {
- int i;
- for(i=0;i
- {
- scanf("%d",a+i);//指针访问
- }
- }
- void OutputArray(int a[],int n)
- {
- int i;
- for(i=0;i
- {
- printf("%4d",*(a+i);//指针访问
- }
- printf("\n");
- }
- //被调函数实现方法四:形参用指针变量,访问都用数组方式
- void InputArray(int *pa,int n);
- void OutputArray(int *pa,int n);
- void InputArray(int *pa,int n)//指针作形参
- {
- int i;
- for(i=0;i
- {
- scanf("%d",&pa[i]);//数组方式访问
- }
- }
- void OutputArray(int *pa,int n)
- {
- int i;
- for(i=0;i
- {
- printf("%4d",pa[i]);//数组方式访问
- }
- printf("\n");
- }
11.3a
编写程序,输入一个3行4列的二维数组,然后输出这个二维数组的元素值。方法一
- //例11.3a 编写程序,输入一个3行4列的二维数组,然后输出这个二维数组的元素值。方法一
- #include
- #define N 4
- void InputArray(int p[][N],int m,int n);
- void OutputArray(int p[][N],int m,int n);
- int main (void)
- {
- int a[3][4];
- printf("Input 3*4 numbers:\n");
- InputArray(a,3,4);//向函数传递的是第0行地址
- OutputArray(a,3,4);
- return 0;
- }
- void InputArray(int p[][N],int m,int n)
- {
- int i,j;
- for(i=0;i
- {
- for(j=0;j
- {
- scanf("%d",&p[i][j]);//使用两层循环就可以完成二维数组的输入
- }
- }
- }
- void OutputArray(int p[][N],int m,int n)
- {
- int i,j;
- for(i=0;i
- {
- for(j=0;j
- {
- printf("%4d",p[i][j]);//使用两层循环同样可以实现二维数组的打印
- }
- printf("\n");//在每一个内层循环结束后添加换行符,相当于实现二维数组的逻辑换行
- }
- }
11.3b
编写程序,输入一个3行4列的二维数组,然后输出这个二维数组的元素值。方法二
- //例11.3b 编写程序,输入一个3行4列的二维数组,然后输出这个二维数组的元素值。方法二
- #include
- #define N 4
- void InputArray(int (*p)[N],int m,int n);//不要忘记(*p)
- void OutputArray(int (*p)[N],int m,int n);
- int main (void)
- {
- int a[3][4];
- printf("Input 3*4 numbers:\n");
- InputArray(a,3,4);//向函数传递的是第0行地址
- OutputArray(a,3,4);
- return 0;
- }
- void InputArray(int (*p)[N],int m,int n)
- {
- int i,j;
- for(i=0;i
- {
- for(j=0;j
- {
- scanf("%d",*(p+i)+j);//相当于先按行移动,再找到对应的列
- }
- }
- }
- void OutputArray(int (*p)[N],int m,int n)
- {
- int i,j;
- for(i=0;i
- {
- for(j=0;j
- {
- printf("%4d",*(*(p+i)+j));//对*(p+i)+j的解引用
- }
- printf("\n");//在每一个内层循环结束后添加换行符,相当于实现二维数组的逻辑换行
- }
- }
11.3c
编写程序,输入一个3行4列的二维数组,然后输出这个二维数组的元素值。方法三
- //例11.3c 编写程序,输入一个3行4列的二维数组,然后输出这个二维数组的元素值。方法三
- #include
- #define N 4
- void InputArray(int *p,int m,int n);//不要忘记(*p)
- void OutputArray(int *p,int m,int n);
- int main (void)
- {
- int a[3][4];
- printf("Input 3*4 numbers:\n");
- InputArray(*a,3,4);//注意a前面的*,这个时候先函数传递的就是0行0列的地址,不同于前面传递0行地址
- OutputArray(*a,3,4);
- return 0;
- }
- void InputArray(int *p,int m,int n)
- {
- int i,j;
- for(i=0;i
- {
- for(j=0;j
- {
- scanf("%d",&p[i*n+j]);//相当于先定位到具体的下标
- }
- }
- }
- void OutputArray(int *p,int m,int n)
- {
- int i,j;
- for(i=0;i
- {
- for(j=0;j
- {
- printf("%4d",p[n*i+j]);//同样先定位到具体的下标
- }
- printf("\n");//在每一个内层循环结束后添加换行符,相当于实现二维数组的逻辑换行
- }
- }
11.4
使用指针数组来重新编写例10.4
- //例11.4 使用指针数组来重新编写例10.4
- #include
- #include
- #define MAX_LEN 10//字符串的最大长度
- #define N 150 //最大参赛国
- void SortString(char *ptr[],int n);
- int main(void)
- {
- int i,n;
- char name[N][MAX_LEN];//使用字符型的二维数组
- char *pStr[N];
- printf("How many countries?");
- scanf("%d",&n);
- getchar();//读走缓冲区的回车符
- printf("Input their name:\n");
- for(i=0;i
- {
- pStr[i]=name[i];//让pStr指向name的第i行
- gets(pStr[i]);//输入第i个字符串到pStr指向的内容
- }
- SortString(pStr,n);//这时候排序的就是pStr
- printf("Sorted results:\n");
- for(i=0;i
- {
- puts(pStr[i]);//输出排序后字符
- }
- return 0;
- }
- void SortString(char *ptr[],int n)
- {
- //指针数组作函数参数,来用交换法实现字符串的排序
- int i,j;
- char *temp=NULL;//因为交换的是字符串的地址值,所以temp需要为指针变量
- for(i=0;i
-1;i++) - {
- for(j=i+1;j
- {
- if(strcmp(ptr[j],ptr[i])<0)//用strcmp()函数实现字符串的比较功能
- {
- temp=ptr[i];//这里就使用赋值运算符即可
- ptr[i]=ptr[j];
- ptr[j]=temp;
- }
- }
- }
- }
11.5
演示命令行的参数与函数main()各形参之间的关系。
- //例11.5 演示命令行的参数与函数main()各形参之间的关系。
- #include
- int main(int argc,char *argv)//带参数的main()函数定义,argc和argv是惯例
- {
- int i;
- printf("The number of command line arguments is:%d\n",argc);
- printf("The program name is:%s\n",argv[0]);
- if(argc>1)
- {
- printf("The other arguments are following:\n");
- for(i=1;i
- {
- printf("%s\n",argv[i]);
- }
- }
- return 0;
- }
11.6
编程输入某班学生的某门课成绩,计算并输出其平均分。学生人数由键盘输入。
- //例11.6 编程输入某班学生的某门课成绩,计算并输出其平均分。学生人数由键盘输入。
- #include
- #include
- void InputArray(int *p,int n);
- double Average(int *p,int n);
- int main(void)
- {
- int *p=NULL,n;
- double aver;
- printf("How many students?");
- scanf("%d",&n);
- p=(int *)malloc(n*sizeof(int));//有多少学生就对应开辟多少空间
- if(p==NULL)//防止出现分配不成功的情况
- {
- printf("No enough memory!\n");//提醒用户空间分配失败
- exit(1);//结束程序
- }
- printf("Input %d score:",n);
- InputArray(p,n);//输入学生成绩
- aver=Average(p,n);//计算平均分
- printf("aver=%.1f\n",aver);
- free(p);//千万不要忘记释放空间
- return 0;
- }
- void InputArray(int *p,int n)
- {
- int i;
- for(i=0;i
- {
- scanf("%d",&p[i]);
- }
- }
- double Average(int *p,int n)
- {
- int i,sum=0;
- for(i=0;i
- {
- sum+=p[i];
- }
- return (double)sum/n;//注意强制转换
- }
11.7
编程输入m个班学生(每班n个学生)的某门课成绩,计算并输出平均分。班级数和每班学生数由键盘输入。
- //例11.7 编程输入m个班学生(每班n个学生)的某门课成绩,计算并输出平均分。班级数和每班学生数由键盘输入。
- #include
- #include
- void InputArray(int *p,int m,int n);
- double Average(int *p,int m,int n);
- int main(void)
- {
- int *p=NULL,m,n;
- double aver;
- printf("How many classes?");
- scanf("%d",&m);
- printf("How many stuents in a class?");
- scanf("%d",&n);
- p=(int *)calloc(m*n,sizeof(int));//申请内存
- if(p==NULL)//防止出现分配不成功的情况
- {
- printf("No enough memory!\n");//提醒用户空间分配失败
- exit(1);//结束程序
- }
- printf("Input %d score:",n);
- InputArray(p,m,n);//输入学生成绩
- aver=Average(p,m,n);//计算平均分
- printf("aver=%.1f\n",aver);
- free(p);//千万不要忘记释放空间
- return 0;
- }
- void InputArray(int *p,int m,int n)
- {
- int i,j;
- for(i=0;i
- {
- printf("Please enter scores of class %d:\n",i+1);
- for(j=0;j
- {
- scanf("%d",&p[n*i+j]);
- }
-
- }
- }
- double Average(int *p,int m,int n)
- {
- int i,j,sum=0;
- for(i=0;i
- {
- for(j=0;j
- {
- sum=sum+p[n*i+j];
- }
- }
- return (double)sum/n;//注意强制转换
- }
-
相关阅读:
创建一个用户test且使用testtab表空间及testtemp临时表空间并授予其权限,密码随意
智慧的仓库管家——WMS
C++11
投资黄金:如何选择正确的黄金品种增加收益?
算法|每日一题|倍数求和|容斥原理
python面试题总结(一)
Css之使用calc()计算宽高(vw/vh)
(Spark Connect)使用Aerospike的 Spark 连接器
R语言使用rpart包拟合随机森林回归模型:使用predict函数和训练好的模型进行预测推理、使用plot函数可视化线图对比预测值和实际值曲线
postman连接websocket, 建立连接、聊天测试(v8.5.1)
-
原文地址:https://blog.csdn.net/gy200203/article/details/140364387