📄 ex6.cpp
字号:
# include<stdio.h>
void show(long * a,int n) //函数显示以指针a起始的随后的n个元素值
{ for(int k=0;k<n;k++) printf("%d ",a[k]);
printf("-"); //a是long *型的指针形参,匹配long*型的地址
}
long t1[7]={1,2,3,4,5,6,7}; //全局数组t1
void main() //定义两个大小不一的一维数组
{ long t4[4]={1,2,3,4}; //局部数组t4
long *pa[3]={t4,t1}; // pa[2]未赋初始值
long ** pp=pa+1; //pp指向pa[1]
show(pa[0],4); show(pp[0-1],4); // pp[-1]=pa[0]= t4
show(pa[1],7); show(pp[1-1],7); // pp[0]=pa[1]= t7
} //输出结果: 1 2 3 4 -1 2 3 4 -1 2 3 4 5 6 7 -1 2 3 4 5 6 7 -
//[例6.14]二级指针显示指针数组的元素指向的变量的值
#include <stdio.h>
void f(int**pp,int n){ for(int i=0;i<n;i++) printf("%d,",**pp++); }
void main() //pp++指向指针数组的下一个元素,**pp表示间接访问间接变量
{ int x=1,y[ ]={2,3},u[ ][1]={4,5};
int * px[]={&x,&y[0],y+1,u[0],&u[1][0]}; f(px,5); f(px+4,5-4);
for(int** pp=px,i=0;i<5;i++,pp++) printf("%d,",**pp);
} //输出:1,2,3,4,5,5, 1,2,3,4,5,
// [例6.15]二级指针或指针数组作为形参实现求数组的和
#include<stdio.h>
double sum(double** pp,int n,int m=3);// 函数原型中 pp为二级指针形参
double a[ ]={2,3,4}; //定义全局数组a[3]
void main(void)
{ double b[2][3]={1,2,3,4,5,0}; //定义2行3列的局部二维数组
double* x[]={b[1],b[0],a}; //相当于double*x[3];x[0]=b[1];x[1]=b[0];x[2]=a;
const char*fmt="%2.0f,%2.0f,%2.0f"; // sum(x+2,1)求数组a[3]的和
printf(fmt,sum(x,2),sum(x+1,1),sum(x+2,1)); //输出15, 6, 9
} //sum(x,2)求二维数组b[2][3]的和,sum(x+1,1)求二维数组b的第一行之和
double sum(double* pp[],int n,int m) //函数定义中 pp为指针数组形参
{ double s=0 ;int i,j;double *p;
for( i=0;i<n;i++,pp++) //pp++指向实参指针数组的下一个元素
for(j=0,p=*pp;j<m;j++,p++) // p=*pp得到该位置指针数组的元素的值
s+=*p; //p++指向double型数组的下一个元素
return s; //pp[i]或p[j]的值由实参隐含送入
}
double sum1(double* pp[],int n,int m) //函数定义中 pp为指针数组形参
{ double s=0 ; //下标法求数组的和
for(int i=0;i<n;i++) for(int j=0;j<m;j++) s+=pp[i][j];
return s;
} //sum函数与sum1函数完成相同的功能,但sum的效率高,sum1简洁。
//[例6.16]void*指针的编程特点
void* memset(void* pv, int c,size_t n) //入口指针pv指向实参携带的具体类型的地址
{ char * pt= (char *)pv ; // (char *)pv表示强制将void*型指针转换为char*型指针
for(unsigned int k=0;k<n;k++) *pt++=(char)c;
return pv; //返回入口指针pv得到的实参的地址
}
#include <iostream.h> // #include <memory.h>
void main()//函数调用虚实结合对应char*型的地址str隐含地转换为void *型的指针。
{ char str[] = "123456789abcd";
cout << str << " ";
char* result = (char*)memset(str, '8', 9); // 赋值语句对应void*型的地址被
cout << result << endl; //强制地转换为char*型的指针result
} //输出结果:123456789abcd 888888888abcd
// [例6.17] 动态申请一个一维数组
#include<stdio.h>
#include<malloc.h>
void main(void)
{ int m; scanf("%d",&m); //数组的维数m动态实时输入
int * a,k;
if(m%2) a= new int[m]; //相当于在堆空间定义int a[m];
else a=(int*)malloc(m*sizeof(int)); //与上面分支new等价的malloc版本。
for( k=0;k<m;k++) a[k]=k; //在a指向堆空间时不要改动a的值
int *p= a; //设置另一个指针p遍历访问堆空间
for (k=0;k<m;k++,p++) printf("a[%d]=%d ",k,*p);
if(m%2) delete [ ] a; // delete [ ] a匹配a= new int[m]
else free(a); // free(a) 匹配a=(int*)malloc(m*sizeof(int))
} //动态运行结果为:4( a[0]=0 a[1]=1 a[2]=2 a[3]=3
//[例6.18] 申请一个二维数组,第一个下标是可变的(多学时)。
#include<stdio.h>
#include<malloc.h>
void main(void)
{ const int N=4; //声明一个main函数体中的int常数N
int m,k,j; scanf("%d",&m); //二维数组的行维数m动态实时输入
int (* d)[N]; //定义一个指向二维数组的指针d
if(m%2) d= new int[m][N]; //相当于在heap空间定义int d[m][N]
else d=(int (*)[N])malloc(m*N*sizeof(int));//与上面分支new等价的malloc版本
for( k=0;k<m;k++) //在d指向堆空间时不要改动d的值
for( j=0;j<N;j++) d[k][j]=k*N+j;
int (*q)[N]= d; //定义另一个数组指针q以简化寻址计算
for (k=0;k<m;k++,q++) //因为d不便于变动,而让q进行q++的变动。
{ int *p =*q; //定义int*型指针p,循环中p=*q相当于p=d[k]
for( j=0;j<N;j++) printf("d[%d][%d]=%d ",k,j,p[j]);
printf("\n");
} // delete [ ] d匹配d= new int[m][N]
if(m%2) delete [ ] d; //动态运行输出结果:2(
else free(d); //d[0][0]=0 d[0][1]=1 d[0][2]=2 d[0][3]=3
} //d[1][0]=4 d[1][1]=5 d[1][2]=6 d[1][3]=7
//[例6.19] 动态的二维数组pp[M][N]分配,维数M,N都可实时输入(多学时选讲)
typedef long type;
#include<iostream.h>
#include<malloc.h>
#include<process.h> // 包含原型void exit(int);exit表示退出运行程序
void main(void)
{ type** pp; //定义二级指针,pp的生存期与可见性与变量相同。
cout<<"input number M:"; int M=2,N=6;
cin>>M;
pp=(type**)malloc(M*sizeof(type*));//二级指针指向堆空间,申请内存存放指针数组
//type** pp= new type* [M]; //相当于定义一个指针数组type* pp[M];
if(pp==NULL) exit(1); //此时指针数组的元素没有初始化
cout<<"input number N:"; cin>>N;
int j ;for(j=0;j<M;j++)
{ //pp[j]=new type[N]; //初始化指针数组的每一元素
pp[j]=(type*)malloc(N*sizeof(type));//为指针元素申请内存存放type型的数组
if(pp[j]==NULL) exit(1); //pp[j]和pp[j+1]未必具有相邻的关系
} //在关联堆空间期间,不要改变pp、pp[j]的值
int k ;for(k=0;k<M;k++) //程序此时可对元素pp[j][k]进行各种运算
for( j=0;j<N;j++) pp[k][j]=k*N+j+1;
for (k=0;k<M;k++)
{ cout<<endl;
for(j=0;j<N;j++) cout<<" pp["<<k<<"]["<<j<<"]="<<pp[k][j];
}
for(j=0;j<M;j++)
if(pp[j]!=NULL) free(pp[j]);//delete [ ] pp[j] ;释放指针数组每一元素占有的内存
if(pp!=NULL) free(pp);// delete [] pp ; 释放指针数组占有的内存
}
// [例6.20] char* p=(char*)a 表达式将long*型地址映射给char*型指针
#include <stdio.h>
void main()
{ long a[2]={0x61626364,0x65666768}; char* p=(char*)a;
for( int k=0;k<8;k++,p++) printf("%c-%x ",*p,*p);
} //输出:d-64 c-63 b-62 a-61 h-68 g-67 f-66 e-65
// [例6.21]一级指针遍历三维数组
#include <stdio.h>
void main()
{ const int L=2,M=3,N=2;
int s[L][M][N]={1,2,3,4,5,6,7,8,9,10,11,12};
int b[L*M*N]; //定义一维数组b,其内存大小同多维数组s
int *p=(int*)s; int *q=b; //定义指针p,q。p强制指向数组s,q指向数组b
int k ;for(k=0;k<L*M*N;k++) *q++=*p++;//访问遍历连续的内存空间。
q-=L*M*N;
for(k=0;k<L*M*N;k++,q++) printf("%d,%d*",*q,b[k]);
} //输出结果:1,1*2,2*3,3*4,4*5,5*6,6*7,7*8,8*9,9*10,10*11,11*12,12*
// [例6.22]一维内存空间张成多维数组
#include <stdio.h>
void main()
{ const int L=2,M=3,N=2; int i=0,j=0,k=0;
int b[L*M*N]={1,2,3,4,5,6,7,8,9,10,11,12}; //定义int型 b[12]
int (*s)[M][N]=(int (*)[M][N])b; //定义int(*)[3][2]的指针s,强制指向一维数组b
for(i=0;i<L;i++) //相当于将一维数组b张成s[2][3][2]
for(j=0;j<M;j++) for(k=0;k<N;k++) printf("%d ",s[i][j][k]);
int (*d)[L*N]=(int (*)[4])b; //定义int(*)[4]的指针d,强制指向一维数组b
for(j=0;j<M;j++) //相当于将b数组张成d[3][4]
for(k=0;k<L*N;k++) printf("%d ",d[j][k]);
} //输出结果:1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12
//[例6.23]指针的匹配和转换
#include<stdio.h>
void main(void)
{ int i,b[3][2]={1,2,3,4,5,6}; //定义二维数组b
int (*q)[3]=(int(*)[3])b; //将int(*)[2]的地址b转换为int(*)[3]的地址
for( i=0;i<2;i++) printf("[%d,%d,%d]\t",q[i][0] ,q[i][1],q[i][2]);
int* pa[]={b[2],b[1],b[0]}; //指针数组pa通过初始化语句完成赋值
int** pp=pa; //二级指针pp指向指针数组pa
for(i=0;i<3;i++) printf("[%d,%d]\t",pp[i][0] ,pp[i][1]);
} //输出 [1,2,3] [4,5,6] [5,6] [3,4] [1,2]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -