《测绘程序设计(https://www.doczj.com/doc/8a14116346.html,)》上机实验报告
(Visual C++.Net)
实验3 数组、指针与函数
班级:
学号:
姓名:
序号:
二零一零年三月
实验3 数组、指针与函数
一、实验目的
?掌握数组的定义、引用及应用方法。
?掌握指针与动态数组。
?掌握函数的定义、引用及应用方法。
二、实验内容
1.求任意多边形面积
多边形面积计算原理及算法
计算原理:
例如上图:
)
)((2
1))((2
1))((2
1))((2
14114344323321221y y x x y y x x y y x x y y x x P -++
-++
-++
-+=
面积计算的算法:
经整理后得:)11,,2,1()
)((2
1
1
11
=+==-+=
∑=++i n i n i Y Y X X P n
i i i i i 时,;当
设计思路:
因为计算多边形面积的数据随多边形顶点数的增加而增加,因此要编写一个分割字符串的函数,使输入的数据第一行表示多边形类型,接下来的每一行依次表示一个顶点的坐标,X 与Y 之间用逗号隔开。
创建一个二维数组,行数即顶点个数,列数为2,用来保存各顶点的坐标。调用Split 函数分离,获取各顶点坐标数据 界面设计:
由1个静态框、2个文本框和2个命令按钮组成。
具体见运行结果的输出界面
主要代码:
ComAreaDlg.cpp
void CComAreaDlg::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
OnCancel();
}
CString * CComAreaDlg::SplitString(CString str, char split, int& iSubStrs)
{
int iPos = 0; //分割符位置
int iNums = 0; //分割符的总数
CString strTemp = str;
CString strRight;
//先计算子字符串的数量
while (iPos != -1)
{
iPos = strTemp.Find(split);
if (iPos == -1)
{
break;
}
strRight = strTemp.Mid(iPos + 1, str.GetLength());
strTemp = strRight;
iNums++;
}
if (iNums == 0) //没有找到分割符
{
//子字符串数就是字符串本身
iSubStrs = 1;
return NULL;
}
//子字符串数组
iSubStrs = iNums + 1; //子串的数量= 分割符数量+ 1
CString* pStrSplit;
pStrSplit = new CString[iSubStrs];
strTemp = str;
CString strLeft;
for (int i = 0; i < iNums; i++)
{
iPos = strTemp.Find(split);
//左子串
strLeft = strTemp.Left(iPos);
//右子串
strRight = strTemp.Mid(iPos + 1, strTemp.GetLength()); strTemp = strRight;
pStrSplit[i] = strLeft;
}
pStrSplit[iNums] = strTemp;
return pStrSplit;
}
void CComAreaDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
int iLine;
//分行并存入字符串数组
CString *pstrLine=SplitString(strCoordData,13,iLine);
if(iLine<4)
{
MessageBox(_T("输入的数据不完整!"));
return;
}
int iApexCount=iLine-1;//多边形顶点个数
short npolygonType;//多边形类型,
double (*cApex)[2];
cApex=new double[iApexCount][2];//顶点坐标值
CString *strTmp=NULL;
int n;
npolygonType = _ttoi(pstrLine[0]); //第一行为多边形类型
//逐行用Split函数分离,获取各顶点坐标数据
for(int i=0;i { strTmp = SplitString(pstrLine[i+1], ',',n);//分割第三行 cApex[i][0] = _tstof(strTmp[0]); cApex[i][1] = _tstof(strTmp[1]); if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } } if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } double Area=0.0;//多边形面积 for(int i=0;i { if(i==iApexCount-1) { //i+1=0; Area = Area +(0.5)*(cApex[0][0]+cApex[i][0])*(cApex[0][1]-cApex[i][1]); } else Area = Area +(0.5)*(cApex[i+1][0]+cApex[i][0])*(cApex[i+1][1]-cApex[i][1]); //计算面积} //输出结果 strResult.Format(_T("%s%.1fmm\r\n"), _T("面积S=:"),Area); //_T("序号 "),_T("调整后H (m) ")); UpdateData(FALSE); //释放内存 if(cApex!=NULL) { delete [] cApex; cApex=NULL; } } 运行结果: 2.由三角形三个边长求内角函数 计算公式: bc a c b A 2cos 2 2 2 -+= ac b c a B 2cos 2 2 2 -+= ab c b a C 2cos 2 2 2 -+= 设计思路: 已知三角形三个边长求三角形三个内角算法简单,需要的数据也少,顺序结构即可实现。为了更加熟悉函数的调用,我编写了一个函数计算三内角,在计算的主程序中调用它就可以达到效果。函数的返回值不能为多值,因此形参中我用了引用做函数参数。 界面设计: 界面很简单,三个文本框输入已知的三条边长,三个文本框输出所求结果。 具体见运行结果的输出界面 主要代码 文件 SolveTriangleDlg.cpp const double PI=3.1415926; //将弧度转化成度分秒形式 double Rad_To_Dms(double Rad) { double dDeg,dDms; //十进制角度及度分秒格式角度,控制变量 //用于存放度分秒三个值的变量 int iDegree,iMin; double dSec; double dTmp; dDeg=Rad*180/PI; //弧度转化为度 //度转化成度分秒 iDegree=int(dDeg); dTmp=(dDeg-iDegree)*60; iMin=int(dTmp); dSec=(dTmp-iMin)*60; dDms=iDegree+double(iMin)/100+dSec/10000; return dDms; } //已知三角形三边长,求三内角 void SolveTriangle(double a,double b,double c,double &A,double &B,double &C) { ///double dAngle[3]={0,0,0}; A=acos((b*b+c*c-a*a)/(2*b*c)); B=acos((a*a+c*c-b*b)/(2*a*c)); C=acos((a*a+b*b-c*c)/(2*a*b)); } void CSolveTriangleDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); /*double *dAngle; dAngle=*/ SolveTriangle(a,b,c,A,B,C); A=Rad_To_Dms(A); B=Rad_To_Dms(B); C=Rad_To_Dms(C); UpdateData(FALSE); } void CSolveTriangleDlg::OnBnClickedCancel() { // TODO: 在此添加控件通知处理程序代码 OnCancel(); } void CSolveTriangleDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 OnOK(); } 运行结果: 3.由已知平面外接圆上三点坐标计算圆心坐标函数 计算公式为: g x b a x a c x c b y g y b a y a c y c b x 2)()()(2)()()(3 2103 210-+-+-- =-+-+-= 3 122311232 3 2 32 22 22 12 1)()()(;;x y y x y y x y y g y x c y x b y x a -+-+-=+=+=+= 设计思路: 已知三角形三个边长求三角形三个内角算法简单,需要的数据也少,顺序结构即可实现。为了更加熟悉函数的调用,我编写了一个函数计算三内角,在计算的主程序中调用它就可以达到效果。函数的返回值不能为多值,因此形参中我用了引用做函数参数。 界面设计: 界面很简单,三个文本框输入已知的三条边长,三个文本框输出所求结果。 具体见运行结果的输出界面 主要代码: 文件ComputeCoordinateDlg.cpp void CComputeCoordinateDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); double a,b,c; double g; a=X1*X1+Y1*Y1; b=X2*X2+Y2*Y2; c=X3*X3+Y3*Y3; g=(Y3-Y2)*X1+(Y1-Y3)*X2+(Y2-Y1)*X3; Xo=((b-c)*Y1+(c-a)*Y2+(a-b)*Y3)/(2*g); Yo=-((b-c)*X1+(c-a)*X2+(a-b)*X3)/(2*g); UpdateData(FALSE); } 运行结果: 输入位于圆上的三个点的坐标,求圆心坐标。 4.极坐标法求待定点坐标函数 设计思路: 1)编写度分秒及弧度之间相互转换的函数、方位角计算的函数。 2)求线段AB的方位角。 3)求线段AP的方位角,并转化为弧度。 4)根据极坐标法求待定点 P的坐标。 界面设计: 界面很简单,8个文本框,8个静态框和三个命令按钮。 具体见运行结果的输出界面 主要代码: 文件PolarCoordinatesDlg.cpp const double PI=3.1415926; //将弧度转化成度分秒形式 double Rad_To_Dms(double Rad) { double dDeg,dDms; //十进制角度及度分秒格式角度,控制变量 //用于存放度分秒三个值的变量 int iDegree,iMin; double dSec; double dTmp; dDeg=Rad*180/PI; //弧度转化为度 //度转化成度分秒 iDegree=int(dDeg); dTmp=(dDeg-iDegree)*60; iMin=int(dTmp); dSec=(dTmp-iMin)*60; dDms=iDegree+double(iMin)/100+dSec/10000; return dDms; } //将度分秒形式转化为弧度 double Dms_To_Rad(double dDms) { int iDegree,iMin; double dSec; //分别用于存放度、分、秒值的变量 double dDeg; //十进制角度,控制变量 double dRad; //弧度 iDegree=int(dDms); //截取度 iMin=int((dDms-iDegree)*100); //截取分 dSec=((dDms-iDegree)*100-iMin)*100; //获取秒 dDeg=iDegree+double(iMin)/60+dSec/3600; //先把分秒转化成度,再相加 dRad=dDeg*PI/180; //转化为弧度 return dRad; } //计算方位角的函数 double TriAzimuth(double X1,double Y1,double X2,double Y2) { double dx,dy; double A; //角度,控制变量 dx=X2-X1; dy=Y2-Y1; if(dx>0) { if(dy>0) A=atan(dy/dx); //A为第一象限角 else if(dy<0) A=atan(dy/dx)+2*PI; //A为第四象限角else A=0; //A=0度 } else if(dx<0) { if(dy>0) A=atan(dy/dx)+PI; //A为第二象限角 else if(dy<0) A=atan(dy/dx)+PI; //A为第三象限角else A=2*PI; //A=180度 } else { if(dy>0) A=PI; //A=90度 else if(dy<0) A=3*PI; //A=270度 else A=0; } A=Rad_To_Dms(A); //将弧度转化为度分秒形式 return A; } void CPolarCoordinatesDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); doubleαab,αap; αab= TriAzimuth(Xa,Ya,Xb,Yb); //反算AB的方位角αap=αab+β; //求AP的方位角 αap=Dms_To_Rad(αap); //转化为弧度 Xp=Xa+Dap*cos(αap); Yp=Ya+Dap*sin(αap); UpdateData(FALSE); } void CPolarCoordinatesDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 OnOK(); } void CPolarCoordinatesDlg::OnBnClickedCancel() { // TODO: 在此添加控件通知处理程序代码 OnCancel(); } 运行结果: 5.交会定点计算函数设计 把前面学过的前方交会、测边交会、后方交会程序写成函数的形式,然后再 通过主程序调用 设计思路: 该程序内容多,代码繁琐,应用的函数也多,因此先添加了一个项,用来存储功能函数,如度分秒向度转换的函数、计算前方交会的函数、计算测边交会的函数、计算后方交会的的函数。 该程序需实现三种交会方式,因此要用到选择结构。定义一个变量iMethod,当它分别为1、2、3时分别执行前方交会、测边交会、后方交会。调用Split 函数分离,获取观测数据。 界面设计: 界面比较复杂,有四个文本框,一个文本框添加了double型变量iMethod,用来选择交会方式,一个文本框用来输入观测数据,其具体属性为: 其它两个文本框用来输出待定点坐标,添加的变量皆为double型。 主要代码: 文件1 Fun.h #pragma once double Dms_To_Rad(double dDms); void ForwardIntersection(double X1,double Y1,double X2,double Y2,doubleα,double β,double &X,double &Y); void SideIntersection(double Xa,double Ya,double Xb,double Yb,double Dap,double Dbp,double &X,double &Y); void Resection(double Xa,double Ya,double Xb,double Yb,double Xc,double Yc,double α,doubleβ,doubleγ,double &X,double &Y); 文件2 Fun.cpp #include"stdafx.h" #include"Fun.h" #include const double PI=3.1415926; //将度分秒形式转化为弧度 double Dms_To_Rad(double dDms) { int iDegree,iMin; double dSec; //分别用于存放度、分、秒值的变量 double dDeg; //十进制角度,控制变量 double dRad; //弧度 iDegree=int(dDms); //截取度 iMin=int((dDms-iDegree)*100); //截取分 dSec=((dDms-iDegree)*100-iMin)*100; //获取秒 dDeg=iDegree+double(iMin)/60+dSec/3600; //先把分秒转化成度,再相加 dRad=dDeg*PI/180; //转化为弧度 return dRad; } //前方交会函数 void ForwardIntersection(double X1,double Y1,double X2,double Y2,doubleα,double β,double &X,double &Y) { α=Dms_To_Rad(α);//将度分秒转化为弧度 β=Dms_To_Rad(β); X=(X1/tan(β)+X2/tan(α)+(Y2-Y1))/(1/tan(α)-1/tan(β)); Y=(Y1/tan(β)+Y2/tan(α)+(X1-X2))/(1/tan(α)-1/tan(β)); } //测方交会程序 void SideIntersection(double Xa,double Ya,double Xb,double Yb,double Dap,double Dbp,double &X,double &Y) { doubleα,β; //角度变量,存储角度BAP的弧度值 double Dab; //AB两点间的距离 Dab=sqrt((Xb-Xa)*(Xb-Xa)+(Yb-Ya)*(Yb-Ya)); α=acos((Dab*Dab+Dap*Dap-Dbp*Dbp)/(2*Dab*Dap)); β=acos((Dab*Dab+Dbp*Dbp-Dbp*Dbp)/(2*Dab*Dbp)); X=(Xa/tan(β)+Xb/tan(α)+(Yb-Ya))/(1/tan(α)-1/tan(β)); Y=(Ya/tan(β)+Yb/tan(α)+(Xa-Xb))/(1/tan(α)-1/tan(β)); } //后方交会 void Resection(double Xa,double Ya,double Xb,double Yb,double Xc,double Yc,double α,doubleβ,doubleγ,double &X,double &Y) { double a,b,c; //边长 double Pa,Pb,Pc; //权值变量 double A,B,C; //存储三个内角值的变量 α=Dms_To_Rad(α); β=Dms_To_Rad(β); γ=Dms_To_Rad(γ); //P1,P2,P3为观测角 //求三角形边长 a=sqrt((Xc-Xb)*(Xc-Xb)+(Yc-Yb)*(Yc-Yb)); b=sqrt((Xc-Xa)*(Xc-Xa)+(Yc-Ya)*(Yc-Ya)); c=sqrt((Xb-Xa)*(Xb-Xa)+(Yb-Ya)*(Yb-Ya)); //求三角形三内角 A=acos((b*b+c*c-a*a)/(2*b*c)); B=acos((a*a+c*c-b*b)/(2*a*c)); C=acos((a*a+b*b-c*c)/(2*a*b)); //求权值 Pa=tan(α)*tan(A)/(tan(α)-tan(A)); Pb=tan(β)*tan(B)/(tan(β)-tan(B)); Pc=tan(γ)*tan(C)/(tan(γ)-tan(C)); //求待测点坐标 X=(Pa*Xa+Pb*Xb+Pc*Xc)/(Pa+Pb+Pc); Y=(Pa*Ya+Pb*Yb+Pc*Yc)/(Pa+Pb+Pc); } 文件3 IntersectionDlg.cpp void CIntersectionDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); int iLine; //分行并存入字符串数组 CString *pstrLine=SplitString(strObsData,13,iLine); /* iLine=3;*/ double Xa,Ya,Xb,Yb,Xc,Yc;//已知坐标值 doubleα,β; //前方交会角度观测值 doubleα,β,γ; //后方交会角度观测值 double Dap,Dbp; //测边交会距离观测值 CString *strTmp=NULL; int n; //分割第一行获得A点坐标 strTmp=SplitString(pstrLine[0], ',',n); Xa= _tstof(strTmp[0]); Ya= _tstof(strTmp[1]); if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } //分割第二行获得B点坐标 strTmp = SplitString(pstrLine[1], ',',n); Xb= _tstof(strTmp[0]); Yb= _tstof(strTmp[1]); if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } //前方交会 if(iMethod==1) { strTmp = SplitString(pstrLine[2], ',',n);//分割第三行 α= _tstof(strTmp[0]); //获得前方交会观测角度 β= _tstof(strTmp[1]); if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } ForwardIntersection( Xa,Ya,Xb,Yb,α,β,Xp,Yp); } //测边交会 else if(iMethod==2) { strTmp = SplitString(pstrLine[2], ',',n); Dap= _tstof(strTmp[0]); //获得测边交会观测距离 Dbp= _tstof(strTmp[1]); if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } SideIntersection(Xa,Ya,Xb,Yb,Dap,Dbp,Xp,Yp); } //后方交会 else if(iMethod==3) { //获得C点坐标 strTmp = SplitString(pstrLine[2], ',',n); Xc= _tstof(strTmp[0]); Yc= _tstof(strTmp[1]); if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } strTmp = SplitString(pstrLine[3], ',',n); α= _tstof(strTmp[0]); //获得后方交会观测角度 β= _tstof(strTmp[1]); γ= _tstof(strTmp[2]); if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } //if(strTmp!=NULL)//释放内存 // { // delete[] strTmp; // strTmp=NULL; // } Resection(Xa,Ya,Xb,Yb,Xc,Yc,α,β,γ,Xp,Yp); } else { MessageBox(_T("输入的数据不完整!")); return; } if(strTmp!=NULL)//释放内存 { delete[] strTmp; strTmp=NULL; } UpdateData(FALSE); } CString * CIntersectionDlg::SplitString(CString str, char split, int& iSubStrs) { int iPos = 0; //分割符位置 int iNums = 0; //分割符的总数 CString strTemp = str; CString strRight; //先计算子字符串的数量 while (iPos != -1) { iPos = strTemp.Find(split); if (iPos == -1) { break; } strRight = strTemp.Mid(iPos + 1, str.GetLength()); strTemp = strRight; iNums++; } if (iNums == 0) //没有找到分割符 { //子字符串数就是字符串本身 iSubStrs = 1; return NULL; } //子字符串数组 C语言实验报告《指针》 学号:__________ 姓名:__________ 班级:__________ 日期:__________ 指导教师:__________ 成绩:__________ 实验五指针 一、实验目的 1、掌握指针的概念、会定义和使用指针变量 2、掌握指向数组的指针变量 3、掌握字符串指针的使用 二、实验内容2、写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。(习题10.6)#include #include long fun(char *p) { 填写程序 } void main() { char s[6]; long n; printf( enter a string:n gets(s); n=fun(s); printf( %ldn ,n); } 一、三、实验步骤与过程 四、程序调试记录 C语言实验报告《综合实验》 学号:__________ 姓名:__________ 班级:__________ 日期:__________ 指导教师:__________ 成绩:__________ 实验六综合实验 一、实验目的 1、掌握C语言中的变量、数组、函数、指针、结构体等主要知识点。 2、掌握C程序的结构化程序设计方法,能使用C语言开发简单的应用程序。 3、掌握C程序的运行、调试方法等。 二、实验内容 编写一个学生信息排序程序。要求: 1、程序运行时可输入n个学生的信息和成绩(n预先定义)。 2、学生信息包括:学号、英文姓名、年龄;学生成绩包括:语文、数学、计算机。 3、给出一个排序选择列表,能够按照上述所列信息(学号、姓名、年龄、语文、数学、计算机)中的至少一个字段进行排序,并显示其结果。 1、使用函数方法定义各个模块。 三、实验步骤与过程 物理实验报告·化学实验报告·生物实验报告·实验报告格式·实验报告模板 四、程序调试记录 实验6 指针1.实验目的和要求 (1)掌握指针的概念、指针变量定义格式和引用。 (2)掌握指针的运算方法。 (3)掌握数组的指针和指向数组的指针变量。 (4)掌握指针与函数的关系。 (5)能正确使用字符串的指针和指向字符串的指针变量。(6)了解指向函数的指针。 (7)了解指向指针变量的指针。 2.实验内容:实验指导书中的实验九。 3.实验步骤 9.1 调试程序,找出程序的错误。 改正后的程序代码(贴图): 运行结果(帖图): 9.2 运行程序: 运行结果:; 9.3 修改程序错误,并运行。 改正后程序代码: 运行结果(帖图): 9.4. 程序填空: 运行结果(请帖图):9.5. 程序填空: 程序填空: #include 9.6 编程(选作) #include 二维数组作为函数参数传递在实际中的应用 周立功教授数年之心血之作《程序设计与数据结构》,电子版已无偿性分享到电子工程师与高校群体,在公众号回复【程序设计】即可在线阅读。书本内容公开后,在电子行业掀起一片学习热潮。经周立功教授授权,本公众号特对本书内容进行连载,愿共勉之。第一章为程序设计基础,本文为1.7.3将二维数组作为函数参数。>>>> 1.7.3 将二维数组作为函数参数>>> 1. 函数原型int data[3][2] = {{1, 2}, {3, 4}, {5, 6}};int sum(int (*pDdata)[2], int size); int sum(int data[3][2], int size); int sum(int data[][2], int size);int sum(int (*pData)[2], int size); int sum(int data[3][], int size); int data[80][3]; int iMax(int *pData, size_t numData) largest = iMax(data, row*col);largest = iMax(data[0], row*col); 1 #includeint working_calc_salary(working_time[month]);int calc_salary(int *working_time);>>> 2. 二维数组的行1 int sum(int (*pData)[2], int size)int (*pData)[2] = data; for(int *ptr = ptr ptr = ptr = data[i]; int data[row][col]; largest = iMax(data[i], col); >>> 3. 二维数组的列int data[row][col], (*pData)[col], i; for(pData = pData 在这里,将pData声明为指向长度为col的整型数组的指针,pData++将pData移到下一行的开始位置。在表达式(*pData)[i]中,*pData代表data的一整行,因此(*pData)[i]选中了该行第i列的那个元素。注意,*pData必须使用括号,否则编译器会认为pData是指针数组,而不是指向数组的指针。 由此可见,只要抓住“变量的三要素(即变量的类型、变量的值和变量的地址)”并贯穿始终,则一切问题将迎刃而解。 C语言程序设计实验报告 1实验目的 (1)掌握指针的概念,会定义和使用指针变量; (2)能正确使用变量的指针和指向变量的指针变量; (3)能正确使用数组的指针和指向数组的指针变量; (4)能正确使用字符串的指针和指向字符串的指针变量; 2实验内容 将一个任意整数插入到已排序的整形数组中,插入后,数组中的数仍然保持有序;要求: (1)整形数组直接由赋值的方式初始化,要插入的整数有scanf()函数数入;(2)算法实现过程采用指针进行处理; (3)输入原始数据以及插入整数后的数据,并加以说明; 3算法描述流程图 4源程序 #include for(i=n-1;a[i]>=w;i--) { a[i+1]=a[i]; } a[i+1]=m; 这一步没有注意a[i++]=m和a[i+1]=m中i++和i+1不同,a[i++]=m是先将的值赋给a[i],然后在执行自增;而在实验过程中忽略了这一点,造成了不必要的麻烦; 8实验心得 通过这次指针实验掌握了指针的概念,会定义和使用指针变量,并且能利用指针来简单化一些问题,给以后的编程带来了很大的便利; C语言程序设计实验报告 1实验目得 (1)掌握指针得概念,会定义与使用指针变量; (2)能正确使用变量得指针与指向变量得指针变量; (3)能正确使用数组得指针与指向数组得指针变量; (4)能正确使用字符串得指针与指向字符串得指针变量; 2实验内容 将一个任意整数插入到已排序得整形数组中,插入后,数组中得数仍然保持有序; 要求: (1)整形数组直接由赋值得方式初始化,要插入得整数有scanf()函数数入; (2)算法实现过程采用指针进行处理; (3)输入原始数据以及插入整数后得数据,并加以说明; 3算法描述流程图 4源程序 #include for(i=n-1;a[i]>=w;i--) { a[i+1]=a[i]; } a[i+1]=m; 这一步没有注意a[i++]=m与a[i+1]=m中i++与i+1不同,a[i++]=m就是先将得值赋给a[i],然后在执行自增;而在实验过程中忽略了这一点,造成了不必要得麻烦; 8实验心得 通过这次指针实验掌握了指针得概念,会定义与使用指针变量,并且能利用指针来简单化一些问题,给以后得编程带来了很大得便利; 杨振平 ●数组元素作实参,对应的形参为变量,一次传递一个元素,采用值传递。 ●数组名作实参,对应的形参为一个数组,一次传递整个数组。 ●数组作参数,其参数传递可理解为形参数组与实参数组共用同一数组空间(即共用实参数组空间)。因此,在函数中,使用形参数组就是在使用实参数组,改变形参数组元素的值就是在改变实参数组元素的值,这一点与引用传递非常相似。 1.一维数组的传递 ?一维数组作形参的声明格式: <类型> <数组名>[] 其中,[]中可以省略数组的长度值。(可认为形参数组与实参数组长度相同) ?对应的实参应为同类型的一维数组名。(仅用数组名) 说明:为了使函数知道需要处理的数组元素的个数,通常给函数再传递一个表示元素个数的整型数。 数组名作为函数参数(续) 例如:一维数组名作为函数的参数。编写函数,计算一个整型数组中从第m个元素(m从0开始)开始的n个元素之和。函数设计: 函数原型:int fun(int b[],int m,int n); 功能:计算数组b中从第m个元素开始的n个元素之和。 主函数设计: 定义并初始化一个整型数组a。 测试1:fun(a,0,10);//求从第0个元素开始的10个元素之和 测试2:fun(a,3,5); //求从第3个元素开始的5个元素之和 int fun(int b[],int m,int n) { int i,s=0; for(i=m;i 实验报告 专业软件工程班级X 班学号_ _ 姓名 实验日期:201X年X月X日报告退发(订正、重做) 课程C程序设计实验实验名称指针 一、实验目的 二、实验环境(描述实验的软件、硬件环境) ①软件环境:windows xp/win7等操作系统,Microsoft Visual C++ 6.0编译器; ②硬件环境:PC机一台 三、实验内容、步骤和结果分析 题目一:输入3个整数,按由小到大的顺序输出 要求: 使用指针方法实现; #include 题目二:将长度为10的整型数组arr中的元素按照从小到大排列并输出 要求: 使用指针方法实现; #include C语言实习报告 题目:指针及其应用 系别: 专业: 姓名: 学号: 日期: 一实验名称:指针及其应用 二实验目的: (1)掌握变量的指针及其基本用法。 (2)掌握一维数组的指针及其基本用法。 (3)掌握指针变量作为函数的参数时,参数的传递过程及其用法。 三实验内容: (1)运行以下程序,并从中了解变量的指针和指针变量的概念。 (2)运行以下程序,观察&a[0]、&a[i]和p的变化,然后回答以下问题: 1.程序的功能是什么? 2.在开始进入循环体之前,p指向谁? 3.循环每增加一次,p的值(地址)增加多少?它指向谁? 4.退出循环后,p指向谁? 5.你是否初步掌握了通过指针变量引用数组元素的方法? (3)先分析以下程序的运行结果,然后上机验证,并通过此例掌握通过指针变量引用数组元素的各种方法。 (4)编写函数,将n个数按原来的顺序的逆序排列(要求用指针实现),然后编写主函数完成: ①输入10个数; ②调用此函数进行重排; ③输出重排后的结果。 四分析与讨论: (1)指针的定义方法,指针和变量的关系。 定义方法: 数据类型 *指针变量名; 如定义一个指向int型变量的指针—— int *p; 则我们可以继续写如下代码—— int a = 4; p = &a; printf("%d", *p); 在这里,我们定义了一个变量a,我们把它理解为内存空间连续的4个字节(int型占用4字节),则这4个字节的空间保存着一个数4。&是取地址符号,即把变量a的地址(即这4个字节的首地址)赋给指针p (记住指针p的类型和变量a的类型要保持一致,否则的话,要进行类型转换)。这样子,指针p就保存着变量a的地址。我们如果把指针p当做内存空间里面另外一个连续的4个字节,那么这4个字节保存的数就是变量a的地址。printf("%d",*p)和printf("%d",a)的结果是一样的。这里的*是取变量符号(与&刚好作用相反,通过变量的地址找到变量),与定义时int *p的*号作用不同(定义时的*表示该变量是个 指针变量,而非是取它指向的变量)。 (2)数组和指针的关系。 指针与数组是C语言中很重要的两个概念,它们之间有着密切的关系,利用这种关系,可以增强处理数组的灵活性,加快运行速度,本文着重讨论指针与数组之间的联系及在编程中的应用。 1.指针与数组的关系 当一个指针变量被初始化成数组名时,就说该指针变量指向了数组。如: char str[20], *ptr; ptr=str; ptr被置为数组str的第一个元素的地址,因为数组名就是该数组的首地址,也是数组第一个元素的地址。此时可以认为指针ptr就是数组str(反之不成立),这样原来对数组的处理都可以用指针来实现。如对数组元素的访问,既可以用下标变量访问,也可以用指针访问。 2.指向数组元素的指针 若有如下定义: int a[10], *pa; pa=a; 则p=&a[0]是将数组第1个元素的地址赋给了指针变量p。 实际上,C语言中数组名就是数组的首地址,所以第一个元素的地址可以用两种方法获得:p=&a[0]或p=a。 这两种方法在形式上相像,其区别在于:pa是指针变量,a是数组名。值得注意的是:pa是一个可以变化的指针变量,而a是一个常数。因为数组一经被说明,数组的地址也就是固定的,因此a是不能变化的,不允许使用a++、++a或语句a+=10,而pa++、++pa、pa+=10则是正确的。由此可见,此时指针与数组融为一体。 3.指针与一维数组 理解指针与一维数组的关系,首先要了解在编译系统中,一维数组的存储组织形式和对数组元素的访问方法。 一维数组是一个线形表,它被存放在一片连续的内存单元中。C语言对数组的访问是通过数组名(数组的起始地址)加上相对于起始地址的相对量(由下标变量给出),得到要访问的数组元素的单元地址,然后再对计算出的单元地址的内容进行访问。通常把数据类型所占单元的字节个数称为扩大因子。 实际上编译系统将数组元素的形式a[i]转换成*(a+i),然后才进行运算。对于一般数组元素的形式:<数组名>[<下标表达式>],编译程序将其转换成:*(<数组名>+<下标表达式>),其中下标表达式为:下标表达式*扩大因子。整个式子计算结果是一个内存地址,最后的结果为:*<地址>=<地址所对应单元的地址的内容>。由此可见,C语言对数组的处理,实际上是转换成指针地址的运算。 数组与指针暗中结合在一起。因此,任何能由下标完成的操作,都可以用指针来实现,一个不带下标的数组名就是一个指向该数组的指针。 一、实验项目名称 指针 二、实验目的 1.掌握指针的基本概念和基本用法。包括:变量的地址和变量的值,指针变量的说明、指针变量的初始化、指针的内容与定义格式、指针的基本运算等; 2.掌握数组与指针的关系并能够利用指针解决数组的相关问题; 3.掌握字符串与指针的关系并能够利用指针处理字符串的问题; 4.掌握指针与函数的关系并能够利用指针处理函数问题; 5.了解指向指针的指针的概念及其使用方法; 6.能够使用指针进行程序设计。 三、实验内容 有关指针的程序设计 1.编程实现:任意输入的10个数,求其平均值。 要求: (1)10个数采用scanf语句读入。 (2)利用指针实现对这10个数的访问。 (3)要求平均值的精度为小数后面2位。 2.编程实现:将一个任意整数插入到一个已排序的整数数组中,插入后数组中的数仍然保持有序。 要求: (1)整数数组由初始化方式输入。任意整数由scanf函数输入; (2)实现过程采用指针处理; (3)输出原始数组数据以及插入数据后的数组数据并加以相应说明。 3.编写函数newcopy(char *new,char *old),它的功能是删除old所指向的字符串中的小写字母,并将所得到的新串存入new中。 要求: (1)在主函数中以初始化方式输入一个字符串; (2)调用newcopy()函数; (3)在主函数中输出处理后的结果。 4.编程实现:输入三个整数,按由大到小的顺序输出。 要求: (1)通过scanf函数输入三个数据并存入三个变量中; (2)利用指针实现从大到小输出; (3)修改程序,将三个整型数据改为字符型数据,输入三个字符,按从大到小数顺序输出; (4)修改程序,将三个字符型数据改为字符串数据,输入三个字符串,按从小到大顺序输出; (5)体会指针对不同数据处理的特点。 四、实验步骤及结果 一、 #include <> void main() { int a[10],n,sum=0; float aver;/* 定义平均数为浮点型*/ int *p=a;/*初始化*/ printf("Please input 10 numbers:\n"); for (n=0;n<10;++n) scanf("%d",&a[n]);/*输入十个数*/ for (n=0;n<10;++n) sum=sum+*(p+n);/*使用指针访问数据*/ aver=(float)sum/n; printf("Average is %.2f",aver);/*精确到小数点后两位*/ } 二、 #include <> void arr(int *a,int n);/*定义排序函数*/ void insert(int *a,int num);/*插入并排序函数*/ int n=10;/*定义数据个数,可修改*/ void main() 实验一进制转换一、实验要求 采用模块化程序设计完成进制转换。由键盘输入一个十进制正整数,然后将该数转换成指定的进制数(二、八、十六) 形式输出。指定的进制由用户输入。 二、实验目的 1、熟悉C 环境的安装、使用。 2、承上启下,复习《C 程序设计》等基础课程的知识。 3、掌握C 语言编程的方法。 三、预备知识 1、VC6.0的安装与使用。 2、C 程序设计基础知识。 四、实验内容 采用模块化程序设计完成进制转换。 五、程序框图 六、程序清单 1. 编写主函数:输入需转换的数与转换的进制 2. 编写子函数 (1)函数转换为除16进制以外的进制转换算数编程,使用while 循环实现计算进制 的转换,并输出转换后的数字; (2)函数转换为16进制,用while 函数实现16进制转换的计算并输出16进制转换后的数据; 3. 编写数组,关于16进制的一系列字符 4. 编写主函数加入do while 使函数可以循环。 七、实验步骤 #include } else { while(n) { a[++i]=num[n%16]; n/=16; } while(i!=-1) printf("%c",a[i--]); printf("\n"); } } int main() { int a, c; 仲恺农业工程学院实验报告纸 信息学院(院、系)专业班C语言程序设计课 实验目的: (1)通过实验进一步掌握指针的概念,会定义和使用指针变量。 (2)能正确使用指针数组和指向数组的指针变量。 (3)能正确使用字符指针变量。 实验内容与总结: 编程练习-要求用指针方法处理。 1、写一个函数,求字符串的长度。在main函数中输入字符串,并输出其长度。 程序如下: #include #include 可以用二维数组名作为实参或者形参,在被调用函数中对形参数组定义时可以指定所有维数的大小,也可以省略第一维的大小说明,如: void Func(int array[3][10]); void Func(int array[][10]); 二者都是合法而且等价,但是不能把第二维或者更高维的大小省略,如下面的定义是不合法的: void Func(int array[][]); 因为从实参传递来的是数组的起始地址,在内存中按数组排列规则存放(按行存放),而并不区分行和列,如果在形参中不说明列数,则系统无法决定应为多少行多少列,不能只指定一维而不指定第二维,下面写法是错误的: void Func(int array[3][]);实参数组维数可以大于形参数组,例如实参数组定义为: void Func(int array[3][10]); 而形参数组定义为: int array[5][10]; 这时形参数组只取实参数组的一部分,其余部分不起作用。 对于数组int p[m][n]; 如果要取p[i][j]的值(i>=0 && i c语言实验报告(同名3848) C语言程序设计实验报告 1实验目的 ⑴掌握指针的概念,会定义和使用指针变量; ⑵能正确使用变量的指针和指向变量的指针变量; ⑶能正确使用数组的指针和指向数组的指针变量; ⑷能正确使用字符串的指针和指向字符串的指针变量。 2实验内容 编写函数upCopy(char *new,char *old),将old指针所指向字符串中的大写字母复制到new指针指向的字符串中,并在主函数中调用该函数。 要求: ①画出算法的流程图。 ②在主函数中以直接初始化的方式输入一个字符串。 ③在主函数中调用upCopy()函数,输出old指针和new指针指向的字符串。 3算法描述流程图 4源程序 #include printf("复制之前的字符串为:"); puts(a); printf("复制之后的字符串为:"); puts(b); } void upCopy(char *new,char *old) { int i,j; j=0; for(i=0;i<20;i++) { if(*(old+i)>=65&&*(old+i)<=90) { *(new+j)=*(old+i); j++; } } *(new+j)='\0'; } 5测试数据 无测试数据。 6运行结果 7出现问题及解决方法 出现的问题是: ①在运用scanf()函数时,由于跟printf()混淆,变量地址的位置忘记输取地 址符“&”,解决办法就是加上取地址符“&”。 ②在找到该插入的位置后,进行后面的数据向后一个数据为调换的时候,没 有注意到“++”运算和“--”运算全部都作用在q上面,都在改变存储的q 的值。解决方法就是用加1的运算来代替自增运算,这样就只有自减运算 在改变q的值,程序即可正常运行。 8实验心得 通过这个实验,掌握了如何定义数组的指针和指向数组的指针变量。同时在程序编写过程中学习到了如何用for循环来寻找数组中某个元素对应的下标。另外,在自己的错误中我还学到了要牢记C语言中各种函数的语法格式,这样才能避免一些不该犯的错误。同时在逻辑上要慎重的同时使用自增和自减运算符,这种逆运算会直接影响变量的存储值。 C语言程序设计实验报告 1实验目的 ⑴掌握指针的概念,会定义和使用指针变量; ⑵能正确使用变量的指针和指向变量的指针变量; ⑶能正确使用数组的指针和指向数组的指针变量; ⑷能正确使用字符串的指针和指向字符串的指针变量。 数组名可以作函数的实参和形参。如: 01. main(){ 02. int array[10]; 03. /* …… */ 04. /* …… */ 05. f(array,10); 06. /* …… */ 07. /* …… */ 08. } 09. 10. f(int arr[],int n); 11. { 12. /* …… */ 13. /* …… */ 14. } array为实参数组名,arr为形参数组名。在学习指针变量之后就更容易理解这个问题了。数组名就是数组的首地址,实参向形参传送数组名实际上就是传送数组的地址,形参得到该地址后也指向同一数组。这就好象同一件物品有两个彼此不同的名称一样。 同样,指针变量的值也是地址,数组指针变量的值即为数组的首地址,当然也可作为函数的参数使用。 【例10-15】 01. float aver(float*pa); 02. main(){ 03. float sco[5],av,*sp; 04. int i; 05. sp=sco; 06. printf("\ninput 5 scores:\n"); 07. for(i=0;i<5;i++)scanf("%f",&sco[i]); 08. av=aver(sp); 09. printf("average score is %5.2f",av); 10. } 11. float aver(float*pa){ 12. int i; 13. float av,s=0; 14. for(i=0;i<5;i++) s=s+*pa++; 15. av=s/5; 16. return av; 17. } 【例10-16】将数组a中的n个整数按相反顺序存放。 算法为:将a[0]与a[n-1]对换,再a[1]与a[n-2] 对换……,直到将a[(n-1/2)]与a[n-int((n-1)/2)]对换。今用循环处理此问题,设两个“位置指示变量”i和j,i的初值为0,j的初值为n-1。将a[i]与a[j]交换,然后使i的值加1,j 的值减1,再将a[i]与a[j]交换,直到i=(n-1)/2为止,如图所示。 程序如下: 01. void inv(int x[],int n)/*形参x是数组名*/{ 02. int temp,i,j,m=(n-1)/2; 03. for(i=0;i<=m;i++){ 04. j=n-1-i; 05. temp=x[i];x[i]=x[j];x[j]=temp; 06. } 07. return; 08. } 09. main(){ 10. int i,a[10]={3,7,9,11,0,6,7,5,4,2}; 11. printf("The original array:\n"); 12. for(i=0;i<10;i++) 13. printf("%d,",a[i]); 14. printf("\n"); 15. inv(a,10); 16. printf("The array has benn inverted:\n"); 17. for(i=0;i<10;i++) 18. printf("%d,",a[i]); 19. printf("\n"); 20. } 对此程序可以作一些改动。将函数inv中的形参x改成指针变量。 C语言实验报告 说明 1,所有程序均用VC6.0编译运行,文件名命名为姓名+日期,因为实验存在补做,所以并不是按照日期先后排列的。 2,为了使截图清晰,手动将运行窗口由“黑底白字”改为了“白底黑字”。 实验2 数据类型、运算符和表达式 一、实验目的: (1)掌握C语言数据类型,熟悉如何定义一个整型、字符型、实型变量、以及对它们赋值的方法。 (2)学会使用C的有关算术运算符,以及包含这些运算符的表达式,特别是自加(++)和自减(――)运算符的使用。 (3)掌握C语言的输入和输出函数的使用 (4)进一步熟悉C程序的编辑、编译、连接和运行的过程。 三、程序调试与问题解决: (1)输人并运行下面的程序 #include char c1,c2; c1='a'; c2='b'; printf("%c %c\n",c1,c2); } ○1运行此程序。 ○2在上面printf语句的下面再增加一个printf语句。printf("%d %d\n",c1,c2); 再运行,并分析结果。 输出结果如图,编译成功,无错误。 ○3将第3行改为 int c1,c2; 再运行,并分析结果。 ○4再将第4、5行改为 c1=a; c2=b; 再运行,并分析结果。 a,b没有定义,编译报错。 ○5再将第4、5行改为 c1=‘’a‘’; c2=‘’b‘’; 再运行,并分析结果。 ○6再将第4、5行改为 c1=300; c2=400; 再运行,并分析结果。 以字符型输出时,输出的将是300,400对应的字符。 (2)输人并运行教材第3章习题3. 6给出的程序 #include 《C语言程序设计》实验报告 实验名称:数组名作为函数的参数 系别: 计算机系专业:计算机科学与技术班级:五班 姓名: 学号: 实验日期: 教师审批签字: 实验8 数组名作为函数的参数 ⒈实验目的 ⑴掌握数组名作为函数参数的基本使用方式。 ⑵掌握与数组有关的算法(特别是排序算法)。 ⒉实验内容或实验题目 编程题目:(题目⑴、题目⑵为一组,题目⑶为一组。每个同学每组都必须完成1题) 要求:每道题目分别书写程序,试运行(如何输入,结果如何)。 题目⑴:编写函数实现将数组元素按从小到大的顺序排序,主函数从键盘输入10个整数存入数组,调用函数后输出数组的元素。 题目⑵:用数组名作为函数参数,编写一个比较两个字符串s和t大小的函数strcomp(s,t),要求s小于t时返回-1,s等于t?时返回0,s大于t时返回1。在主函数中任意输入4个字符串,利用该函数求最小字符串。 题目⑶:输入6×6的数组,下面的各要求通过编写函数实现,要求用数组名作为函数参数: ①求出对角线上各元素的和; ②求出对角线上行、列下标均为偶数的各元素的积; ③找出对角线上其值最大的元素和它在数组中的位置。 ⒊算法说明 (用文字或流程图说明。) 题目1: ⒋程序清单 题目⑴: #include C语言程序设计实验报告 专业:班级:日期:成绩: 实验组别:第次实验:指导教师: 学生姓名:学号:同组人姓名: 实验名称:指针实验 一、实验目的 (1)熟练掌握指针的说明、赋值、使用。 (2)掌握用指针引用数组的元素,熟悉指向数组的指针的使用。 (3)熟练掌握字符数组与字符串的使用,掌握指针数组及字符指针数组的用法。 (4)掌握带有参数的main函数的用法。 二、实验内容及要求 1.源程序改错 下面的源程序中是否存在错误?如果存在,原因是什么?如果存在错误要求在计算机上对这个源程序进行调试修改,是之能够正确执行。 源程序: #include do { printf("\t\t1 copy string.\n"); printf("\t\t2 connect string.\n"); printf("\t\t3 exit.\n"); printf("\t\tinput a number(1-3)please! \n"); scanf("%d",&choice); } while(choice<1||choice>5); switch (choice) { case 1: p=strcpy; break; case 2: p=strcat; break; case 3: goto down; } getchar(); printf("input the first string please! \n"); i=0; _______________________ printf("input the second string please!\n"); i=0; _______________________ result=____(a,b); printf("the result is %s\n",result); down: ; return 0; } (2)请上机运行第(1)题程序使之能按下面要求输出结果(注:(输入)表示该行数据是键盘数据): 1.copy string。 2.Connect string。 3.Exit。 Input a number(1-3)please! 2(输入) Input the first string please! The more you learn,(输入) Input the second string please! The more you get.(输入) 数组可以作为函数的参数使用,进行数据传送。 数组用作函数参数有两种形式,一种是把数组元素(下标变量)作为实参使用;另一种是把数组名作为函数的形参和实参使用。 数组元素作函数实参 数组元素就是下标变量,它与普通变量并无区别。 因此它作为函数实参使用与普通变量是完全相同的,在发生函数调用时,把作为实参的数组元素的值传送给形参,实现单向的值传送。【例5-4】说明了这种情况。 【例8-7】判别一个整数数组中各元素的值,若大于0 则输出该值,若小于等于0则输出0值。编程如下:#include C语言实验报告《指针》.doc
c语言实验报告6 指针
二维数组作为函数参数传递在实际中的应用
C语言指针实验报告
C语言指针实验报告
数组名作为函数参数
C语言程序设计—指针—实验报告
c语言指针实验报告
C语言实验六实验报告——指针
C语言实验报告
指针(C语言实验报告)
C语言二维数组作为函数的参数
c语言实验报告(同名3848)
C语言数组名作函数参数
c语言实验报告
《C语言程序设计》数组名作为函数的参数
C语言程序设计实验报告(一)
C语言数组作为函数参数