计算与人工智能概论-问题求解、科学计算与AI应用方法 课件 第7章:指针_第1页
计算与人工智能概论-问题求解、科学计算与AI应用方法 课件 第7章:指针_第2页
计算与人工智能概论-问题求解、科学计算与AI应用方法 课件 第7章:指针_第3页
计算与人工智能概论-问题求解、科学计算与AI应用方法 课件 第7章:指针_第4页
计算与人工智能概论-问题求解、科学计算与AI应用方法 课件 第7章:指针_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

计算与人工智能概论问题求解、科学计算与AI应用方法第7章指针信息科学与工程学院

指针是一种特殊的数据类型,它存储了一个内存地址。通过操作指针,可以间接地访问和修改它所指向的内存区域的内容。指针在C语言中非常常用,掌握指针对于理解C语言以及编写高效的程序至关重要。

通过学习指针,需要掌握以下基本知识:声明指针以及初始化指针;解引用指针:指针运算;指针和数组的关系以及通过指针可以访问数组元素;函数指针和指针函数;动态内存分配和释放;掌握这些基本知识后,可以进一步学习更高级的指针操作,如指针数组、指向指针的指针、结构体指针等。通过实践和练习,逐渐提高对指针的理解和应用能力。任务1:指针基础(函数的输出参数)

任务2:变量数据交换

任务3:一维数组元素互换

任务4:字符串的插入

任务5:马鞍数

任务6:删除字符串中的空格 目录任务1:指针基础(函数的输出参数)

任务描述第6章任务1设计了2函数doubleComputeX(doublev0,doubletheta,doublet)和doubleComputeY(doublev0,doubletheta,doublet),分别用来计算时刻t的炮弹横坐标和纵坐标。从功能完整性的角度来看,计算炮弹坐标的功能如能放进一个函数则显得更为合理。本任务要求设计一个函数,计算炮弹的坐标并将之返回给。任务1:指针基础(函数的输出参数)

相关知识:指针变量的声明与初始化格式:

<数据类型>*<指针变量名>=&<变量名>;示例:intnum=10;//定义一个整数变量int*ptr=#//声明一个指向整数的指针变量,并将num的地址赋给ptrfloatpi=3.14;//定义一个浮点数变量float*fptr=π//声明一个指向浮点数的指针变量,并将pi的地址赋给fptrcharch='A';//定义一个字符变量char*cptr=&ch;//声明一个指向字符的指针变量,并将ch的地址赋给cptr变量假设的内存地址值intnum=10100010int*ptr=&num10041000floatpi=3.1410083.14float*fptr=&pi10121008charch='A'101665char*cptr=&ch;10201016任务1:指针基础(函数的输出参数)

相关知识:取地址与取内容取地址运算符(&):intx=10;int*p=&x;//p指向x的地址取内容运算符(*):intvalue=*p;//value的值为p所指向的变量的值,也就是10*p=20;//将20存入p指向的变量,即value任务1:指针基础(函数的输出参数)

相关知识:指针变量的赋值指针变量的赋值:inta=10;int*p=&a;//指针p指向变量aint*q=p;//指针q也指向变量a*q=12;//q指向的变量a的值修改为12printf(“%d\n”,*p);//输出p指向的变量a的值,为12任务1:指针基础(函数的输出参数)

设计思路函数参数

单向值传递,实参

形参

地址传递,实参形参共用地址空间,改变形参、实参值也会改变(1)调用函数时,使用&运算符获取变量的地址,并将其作为参数传入。(2)函数定义中,对应的参数类型应为指向相应数据类型的指针。(3)在函数体内,通过*(解引用操作符)对指针所指向的内存空间进行赋值或修改。通过地址参数输出炮弹坐标

要完成用一个函数返回横坐标和纵坐标的要求,可以修改程序5.1-1中的函数ComputeX,在原有参数后面增加2个指针类型的输出参数,这两个参数在函数调用时传入两个坐标变量的地址。函数计算出炮弹在时间t的横坐标和纵坐标之后,分别使用解引用方式将计算结果写入指针指向的变量。任务1:指针基础(函数的输出参数)

设计思路函数参数

单向值传递,实参

形参

地址传递,实参形参共用地址空间,改变形参、实参值也会改变(1)调用函数时,使用&运算符获取变量的地址,并将其作为参数传入。(2)函数定义中,对应的参数类型应为指向相应数据类型的指针。(3)在函数体内,通过*(解引用操作符)对指针所指向的内存空间进行赋值或修改。通过地址参数输出炮弹坐标

要完成用一个函数返回横坐标和纵坐标的要求,可以修改程序5.1-1中的函数ComputeX,在原有参数后面增加2个指针类型的输出参数,这两个参数在函数调用时传入两个坐标变量的地址。函数计算出炮弹在时间t的横坐标和纵坐标之后,分别使用解引用方式将计算结果写入指针指向的变量。任务1:指针基础(函数的输出参数)

设计思路:自然语言描述函数的参数:初速度v0,角度theta,时间t,输出参数px,输出参数py函数的返回值:无Step1:计算炮弹在时刻t的横坐标x和纵坐标y;Step2:将x赋给*px,将y赋给*py.任务1:指针基础(函数的输出参数)

问题求解00#include<stdio.h>01#include<math.h>02#definePI3.1415926503#defineg9.804voidComputePos(doublev0,doubletheta,doublet,double*px,double*py){05*px=v0*cos(theta)*t;//计算炮弹的横坐标06*py=v0*sin(theta)*t-0.5*g*t*t;//计算炮弹的纵坐标07}08intmain(){09doublev0=50.0;//初速度m/s10doubletheta=45.0*(PI/180.0);//角度弧度11doublet;//时间12doubleX[1000],Y[1000];//坐标值13doublet_max=(2.0*v0*sin(theta))/g;//计算炮弹的落地时间;14inti;//数组的下标15for(t=0,i=0;t<=t_max;t+=0.1,i++){16ComputePos(v0,theta,t,&X[i],&Y[i]);//计算炮弹的坐标17printf("炮弹在时间%.2lf秒时的坐标为:(%.2f,%.2f)\n",t,X[i],Y[i]);18}19return0;20}任务1:指针基础(函数的输出参数)

任务2:变量数据交换

任务3:一维数组元素互换

任务4:字符串的插入

任务5:马鞍数

任务6:删除字符串中的空格 目录任务2:变量数据交换内容概要1、任务描述2、相关知识3、设计思路4、问题求解任务2:变量数据交换任务描述变量值的交换,目的是将两个变量里面存储的值进行交换。本任务假设变量a的值为10,变量b的值为99,要求编写一个函数,将变量a和b作为参数传入,函数执行完毕后,完成变量a与b值的交换,即a的值为99,b的值为10。aab10999910交换后b任务2:变量数据交换相关知识:指针变量四要素指针变量的类型:指针变量的类型指的是指针变量本身的数据类型,例如int*、float*、char*等。它决定了指针变量在内存中所占的空间大小和操作的规则。指针变量所指向的数据类型:指针变量所指向的数据类型指的是指针变量所存储的内存地址所对应的数据类型。例如,int*类型的指针变量可以指向整数类型的数据,float*类型的指针变量可以指向浮点数类型的数据,以此类推。指针变量指向的内存地址:指针变量存储的是一个内存地址,它指向了内存中的某个位置。这个地址可以是任何有效的内存地址,包括变量的地址、数组的地址、动态分配的内存地址等。指针变量本身的地址:指针变量本身也是一个变量,它在内存中有自己的地址。可以使用`&`运算符获取指针变量本身的地址。任务2:变量数据交换设计思路:直接交换变量的值直接交换变量的值,即交换两个两个变量存储数据的值。生活中的案例:有两个杯子,杯子A装的是白酒,杯子B装的是红酒,要进行交换,可以取一个空杯子C,将A中的白酒倒入杯子C,然后把B中的红酒倒入A,再把C中的白酒倒入B。将空杯子C换成中间变量,倒入的操作换成赋值运算即可完成数据交换:inta=10,b=99;inttemp;temp=a;a=b;b=temp;任务2:变量数据交换设计思路:交换函数实际参数的值交换函数的实际参数:将两个变量作为参数传入函数,希望在函数中交换变量值会失败。失败原因:C语言的参数传递存在从实际参数到形式参数的赋值过程,函数内的数据交换仅针对形式参数,而无法对实际参数造成影响。解决方案:将需要交换数据的两个变量的地址传入函数,即函数的两个参数都是指针,在函数中则通过这两个指针来进行数据的交换。任务2:变量数据交换设计思路:自然语言描述Step1:定义变量a和bStep2:初始化变量a和bStep3:定义指针变量pa和pbStep4:初始化指针变量pa和pb,使pa指向a,pb指向bStep5:定义中间变量tempStep6:完成交换temp=*pa;*pa=*pb;*pb=tempStep7:输出变量a和b的值任务2:变量数据交换问题求解00#include<stdio.h>01voidswap(int*pa,int*pb){02inttemp=*pa;//temp保存a的值

03*pa=*pb;//a的值变成b的值

04*pb=temp;//b的值变成a的值(实际上是a原来的值)

05}06intmain(){07inta=10,b=99;08printf("Beforeswapping,a=%dandb=%d\n",a,b);09swap(&a,&b);//调用swap函数进行交换

10printf("Afterswapping,a=%dandb=%d\n",a,b);11return0;12}任务1:指针基础(函数的输出参数)

任务2:变量数据交换

任务3:一维数组元素互换

任务4:字符串的插入

任务5:马鞍数

任务6:删除字符串中的空格 目录任务3:一维数组元素互换内容概要1、任务描述2、相关知识3、设计思路4、问题求解任务3:一维数组元素互换任务描述有两个长度相同的整型一维数组,arr1=[1,3,5,7,9],arr2=[21,23,25,27,29],要求对两个数组的元素进行位置交换,交换规则为,arr1的第一个元素与arr2的最后一个元素交换,arr1的第二个元素与arr2的倒数第二个元素交换,。。。,交换后,arr1=[29,27,25,23,21],arr2=[9,7,5,3,1],分别使用数组下标和指针操作完成。任务3:一维数组元素互换相关知识1、指向一维数组的指针变量以及初始化2、指针变量的运算3、指针变量操作一维数组任务3:一维数组元素互换相关知识:指向一维数组的指针变量以及初始化定义指针变量:使用指针类型的标识符声明一个指针变量,表示其将指向数组的首地址。例如:int*ptr;表示定义了一个指向整型数组的指针变量ptr初始化指针变量:声明指针变量时初始化:intarr[5]={1,2,3,4,5};int*ptr=arr;这里将数组arr的首地址赋值给指针变量ptr,它将指向数组的第一个元素。使用地址运算符&:intarr[5]={1,2,3,4,5};int*ptr=&arr[0];这里使用&运算符获取数组第一个元素的地址,并将其赋值给指针变量ptr。

声明指针变量后进行赋值:intarr[5]={1,2,3,4,5};int*ptr;ptr=arr;这里先声明了指针变量ptr,然后将数组arr的首地址赋值给它。任务3:一维数组元素互换相关知识:数组名与指针变量的区别特性数组名intarr[]指针int*p类型int[]int*可修改性不可修改可修改sizeof结果整个数组大小指针大小&运算符结果int(*)[]类型int**类型作为函数参数自动转换为int*直接传递指针值任务3:一维数组元素互换相关知识:指针变量的运算指针变量的赋值:inta=10;int*p=&a;指针变量的自增和自减:指针变量的自增和自减操作分别会使指针向后或向前移动一个单位。这个单位取决于指针指向的数据类型的大小。例如:inta[5]={1,2,3,4,5};int*p=a;//p指向数组a的第一个元素

printf("%d\n",*p);//输出1p++;//p指向数组a的第二个元素

printf("%d\n",*p);//输出2p--;//p又指向数组a的第一个元素

printf("%d\n",*p);//输出1任务3:一维数组元素互换相关知识:指针变量的运算指针变量的算术运算:p+1,p+n指针变量之间的运算:两个指针变量之间的运算可以得到它们之间的距离。例如:intA[5]={1,2,3,4,5};int*p=A;//p指向数组a的第一个元素

p=p+3;//p指向a的第4个元素p=p-2;//p指向a的第2个元素任务3:一维数组元素互换相关知识:指针常见的错误指针越界:C语言不检查指针边界,使用指针对数组进行遍历时,需要检查指针指向的位置,确保指针不会指向数组之外的位置。数组名的常量特性:数组名是常量指针,不可修改其指向:intA[5]={1,2,3,4,5};A++;//编译错误!任务3:一维数组元素互换设计思路:用指针遍历一维数组遍历数组元素:使用指针变量p1指向arr1的第一个元素,p2指向arr2的最后一个元素,每次循环时,p1后移,p2前移。图7.9展示了这种遍历方式。任务3:一维数组元素互换设计思路:交换数据交换数据:直接使用前面的swap函数,将P1和P2作为参数传入,即可完成数据的交换。任务3:一维数组元素互换设计思路:自然语言描述Step1:定义数组arr1和arr2,并且初始化为,arr1=[1,3,5,7,9],arr2=[21,23,25,27,29]。Step2:定义变量n,初始化为数组arr1的长度Step3:定义指针变量p1和p2,p1指向数组arr1的第一个元素,p2指向数组arr2的最后一个元素。Step4:循环n次,交换p1和p2所指向的位置的数据,每循环一次,p1指向后一个元素,p2指向前一个元素。Step5:输出数组arr1和arr2。任务3:一维数组元素互换问题求解:指针实现00#include<stdio.h>01voidswap(int*pa,int*pb){02inttemp=*pa;//temp保存a的值

03*pa=*pb;//a的值变成b的值

04*pb=temp;//b的值变成a的值(实际上是a原来的值)

05}06intmain(){07//Step1:定义并初始化数组arr1和arr208intarr1[]={1,3,5,7,9};09intarr2[]={21,23,25,27,29};10intn=sizeof(arr1)/sizeof(int);//Step2:定义并初始化变量n11//Step3:定义指针变量p1和p2分别指向arr1的第一个元素和arr2的最后一个元素12for(int*p1=arr1,*p2=arr2+n-1;p1<arr1+n;p1++,p2--){13swap(p1,p2);//Step4:交换p1和p2所指向的位置的数据14}15//Step5:输出数组arr1和arr216for(inti=0;i<n;i++)printf("%d",arr1[i]);17printf("\n");18for(inti=0;i<n;i++)printf("%d",arr2[i]);19return0;20}任务1:指针基础(函数的输出参数)

任务2:变量数据交换

任务3:一维数组元素互换

任务4:字符串的插入

任务5:马鞍数

任务6:删除字符串中的空格 目录任务4:字符串的插入内容概要1、任务描述2、相关知识3、设计思路4、问题求解任务4:字符串的插入任务描述小雨在默写英文诗歌《Rain》时,写成了“Rainisfallingallaround,itrainsontheumbrellahere,andontheshipsatsea.”,在第一个‘,’后面漏掉原诗中的“itfallsonfieldandtree,”,请将漏掉的诗句插入到默写部分第一个句号后面,形成完整的诗歌。Rainisfallingallaround,itfallsonfieldandtree,itrainsontheumbrellahere,andontheshipsatsea.雨儿在到处飘落,它落在田野和树梢,它落在这里的雨伞上,又落在航海的船只上。任务4:字符串的插入相关知识1、字符串的定义与存储2、字符串的输入与输出3、字符串处理函数4、字符串与指针5、常见错误任务4:字符串的插入相关知识:字符串的定义与存储字符串:一种以字符数组形式存储的连续字符序列,它以字符'\0'(ASCII码值为0)作为结束标志。charstr[]="Hello";//编译器自动在末尾添加'\0'函数strlen:获取字符串的长度(需要包含头文件string.h),字符串长度是指字符串中实际字符的数量,不包括结束符'\0'。#include<string.h>charstr[]="Hello";intlen

=strlen(str);

//len为5intn=sizeof(str);//n为6任务4:字符串的插入相关知识:字符串的输入与输出输出函数printf:charstr[]="Hello";printf("%s",str);//输出Hello输出函数puts函数:puts(str);//输出Hello并自动换行

输入函数scanf:charinput[20];scanf("%s",input);//读取到空白符(空格、Tab、换行)前停止gets函数:gets(input);//危险!不检查输入长度,可能导致缓冲区溢出(C11已废弃)任务4:字符串的插入相关知识:字符串处理函数函数原型功能描述示例size_tstrlen(constchar*str)返回字符串str的长度(不包括结尾的空字符'\0')strlen("Hello")

→5char*strcpy(char*dest,constchar*src)将字符串src复制到目标数组dest中,并返回指向dest的指针strcpy(dest,"Copy")char*strcat(char*dest,constchar*src)将字符串src拼接到目标数组dest的末尾,并返回指向dest的指针strcat(dest,"World")intstrcmp(constchar*str1,constchar*str2)比较字符串str1和str2的大小。如果str1小于str2,返回负值;如果相等,返回0;如果str1大于str2,返回正值strcmp("a","b")

→负值intstrncmp(constchar*str1,constchar*str2,size_tn)比较字符串str1和str2的前n个字符。比较规则与strcmp函数相同strncmp("Hello","Hel",3)char*strchr(constchar*str,intc)在字符串str中查找字符c首次出现的位置,并返回指向该位置的指针。如果未找到,返回NULLstrchr("Hello",'e')char*strstr(constchar*haystack,constchar*needle)在字符串haystack中查找子串needle首次出现的位置,并返回指向该位置的指针。如果未找到,返回NULLstrstr("Hello","el")任务4:字符串的插入相关知识:字符串与指针字符串在内存中以字符数组的形式存储,而字符指针可以指向这个字符数组的首地址。通过指针,可以访问和操作字符串中的每个字符。指针的算术运算(如递增、递减)可以方便地遍历字符串中的字符。例如,p++可以使指针p指向字符串中的下一个字符。charstr[]

="DynamicString";

//使用指针遍历字符串

for(char*p=str;*p!='\0';p++){

printf("%c",*p);//逐字符输出:Dynamic...

}任务4:字符串的插入相关知识:常见错误忘记结束符'\0':在定义字符数组时忘记添加结束符'\0',会导致函数越界访问内存,从而引发未定义行为(如程序崩溃、数据损坏等)。字符串比较误用==在C语言中,==运算符比较的是两个指针的地址值,要比较两个字符串的内容是否相等,应使用strcmp函数。任务4:字符串的插入设计思路:基本求解思路将任务分解为三次字符复制操作:将S1开始到第一个逗号的内容复制到S3;将S2的全部字符一次复制到S3接下来的位置(不包括S2的结束标志);将S1第一个逗号后面的所有字符复制到S3接下来的位置,并在S3后面加上字符串结束符。任务4:字符串的插入设计思路:不使用库函数的实现思路将S1开始到第一个逗号的内容复制到S3char*p1=S1,*p2=S2,*p3=S3;for(;*p1!=',';p1++,p3++)*p3=*p1;//S1逗号之前的字符拷贝到S3*p3++=*p1++;*p3++=*p1++;//逗号和空格拷贝到S3将S2的全部字符一次复制到S3接下来的位置(不包括S2的结束标志);for(;*p2;p2++,p3++)*p3=*p2;//S2拷贝到S3末尾将S1it开始的所有字符复制到S3接下来的位置,并在S3后面加上字符串结束符。for(;*p1;p1++,p3++)*p3=*p1;//S1逗号之后的字符拷贝到S3任务4:字符串的插入设计思路:使用库函数的实现思路将S1开始到第一个逗号的内容复制到S3char*p1=strchr(S1,',');p1+=2;//p1指向S1逗号与空格后的位置intn=p1-S1;//S1的“it”之前的字符个数strncpy(S3,S1,n);//S1的“it”之前的字符拷贝到S3char*p3=S3+n;//p3指向S3完成第一次复制后的空位置将S2的全部字符一次复制到S3接下来的位置(不包括S2的结束标志);strcpy(p3,S2);//S2拷贝到S3末尾将S1第一个逗号后面的所有字符复制到S3接下来的位置,并在S3后面加上字符串结束符。p3+=strlen(S2);//p3指向S3完成第二次复制strcpy(p3,p1);//S1剩下的字符拷贝到S3末尾任务4:字符串的插入设计思路:自然语言描述Step1:定义字符数组并初始化,其中S1初始化为“Rainisfallingallaround,itrainsontheumbrellahere,andontheshipsatsea.”;S2初始化为“itfallsonfieldandtree,”;S3定义足够长度,可以容纳S1和S2的内容和结束标志,S3所有内容初始化为0。Step2:定义字符指针变量p1、p2和p3分别指向字符数组S1、S2和S3。Step3:用字符指针p1遍历字符数组S1,如果不是逗号‘,’,将字符复制到S3,遇到逗号退出循环,将逗号和空格复制到S3,p1和p3后移一位。Step4:用字符指针p2遍历字符数组S2,将p2所指向的内容复制到p3,到S2的结束标志为止,每复制一次,p2和p3后移一位。Step5:用p1遍历字符数组S1剩余的字符,到S1的结束标志为止,每遍历一次,将p1所指的字符复制到p3,p1和p3后移一位。Step6:输出字符串S3。任务4:字符串的插入问题求解:不使用库函数00#include<stdio.h>01#include<string.h>02intmain()03{04 charS1[]="Rainisfallingallaround,itrainsontheumbrellahere,andontheshipsatsea.";05 charS2[]="itfallsonfieldandtree,";06 charS3[sizeof(S1)+sizeof(S2)+1]={0};07 char*p1=S1,*p2=S2,*p3=S3;08 for(;*p1!=',';p1++,p3++)*p3=*p1;//S1逗号之前的字符拷贝到S309 *p3++=*p1++;*p3++=*p1++;//逗号和空格拷贝到S310 for(;*p2;p2++,p3++)*p3=*p2;//S2拷贝到S3末尾11 for(;*p1;p1++,p3++)*p3=*p1;//S1逗号之后的字符拷贝到S312 printf("%s\n",S3);13}任务4:字符串的插入问题求解:使用库函数00#include<stdio.h>01#include<string.h>02intmain()03{04 charS1[]="Rainisfallingallaround,itrainsontheumbrellahere,andontheshipsatsea.";05 charS2[]="itfallsonfieldandtree,";06 charS3[sizeof(S1)+sizeof(S2)+1]={0};07 char*p1=strchr(S1,',');p1+=2;//p1指向S1逗号与空格后的位置08 intn=p1-S1;//S1的“it”之前的字符个数09 strncpy(S3,S1,n);//S1的“it”之前的字符拷贝到S310 char*p3=S3+n;//p3指向S3完成第一次复制后的空位置11 strcpy(p3,S2);//S2拷贝到S3末尾12 p3+=strlen(S2);//p3指向S3完成第二次复制后的空位置13 strcpy(p3,p1);//S1剩下的字符拷贝到S3末尾14 printf("%s\n",S3);15}任务1:指针基础(函数的输出参数)

任务2:变量数据交换

任务3:一维数组元素互换

任务4:字符串的插入

任务5:马鞍数

任务6:删除字符串中的空格 目录任务5:马鞍数内容概要1、任务描述2、相关知识3、设计思路4、问题求解任务5:马鞍数任务描述马鞍数,是指数阵n*m中在行上严格最小而在列上严格最大的数。例如,给定一个5行6列的矩阵,具体数据如下:167895456786345217234908567689那么第5行第1列的数据5就是该方阵的马鞍数。可以证明,一个数阵中要么存在唯一一个马鞍数,要么不存在马鞍数。请编写程序,求出上面矩阵中的马鞍数,输出对应的行列数,如果矩阵不存在马鞍数,输出“该矩阵不存在马鞍数”。任务5:马鞍数相关知识1、指向二维数组元素的指针2、二维数组名与行指针3、行指针的解引用任务5:马鞍数相关知识:指向二维数组元素的指针二维数组在内存中以行优先(row-majororder)的方式连续存储。intarr[3][4];编译器分配一块连续内存空间,依次存储arr[0][0]、arr[0][1]、…、arr[2][3]共12个整数。通过指向二维数组元素的指针,用该指针的移位操作来遍历该二维数组的全部元素//遍历二维数组intA[3][4]={{4,5,2,7},{2,5,6,1},{9,0,5,2}};for(int*p=&A[0][0];p<&A[0][0]+3*4;p++){

//用指针遍历二维数组

//访问数组元素}任务5:马鞍数相关知识:二维数组名与行指针一个二维数组名字的类型为“指向包含4个整数的数组的指针”(int(*)[4]),它存储的是二维数组第一行的内存地址。定义int(*)[4]类型的指针p并使用二维数组名arr对其进行初始化,则指针p指向二维数组的第一行,执行一次p++操作后,指针p将跳过4个元素指向数组的第二行。任务5:马鞍数相关知识:行指针的解引用对行指针进行解引用,将获得指向该行第一个元素的指针任务5:马鞍数设计思路用指针遍历二维数组的一行用行指针通过算数运算指向指定的行对行指针进行解应用操作获得指向行首元素的指针利用指向行首元素的指针对该行进行遍历int(*prow)[4]

=arr;

//prow初始化为指向二维数组arr的第一行prow++;

//指向第二行for

(int*p=*prow;*p<*prow+4;p++){

//获得指向第二行首元素的指针然后进行遍历

//访问第2行的元素}任务5:马鞍数设计思路用指针遍历二维数组的一列初始化一个指向该列首元素的指针通过指针的算数运算对指针加上每行元素总数,将指针指向该列的下一个元素for(int*p=&A[0][2];p<&A[0][2]+9;p+=4){ //访问元素}任务5:马鞍数设计思路:自然语言描述Step1:定义符号常量N和M,用于表示矩阵的行数和列数。Step2:定一个二维整形数组A,初始化为{{1,6,7,8,9,5},{4,5,6,7,8,6},{3,4,5,2,1,7},{2,3,4,9,0,8},{5,6,7,6,8,9}}。Step3:定义一个指向数组A的行指针prow,指向数组的第一行。Step4:定义整型变量rowmin,colmax,分别用于存储行最小值和列最大值。Step5:对数组的行进行遍历。Step6:对当前行进行遍历,求出该行的最小值rowmin,并记录最小值的列下标k,然后遍历最小值所在列,求出该列的最大值colmax,记录最大值的行下标m;Step7:若rowmin与colmax的值相等,rowmin为马鞍数,输出马鞍数,退出程序。Step8:若遍历了所有行,依然没有找到马鞍数(没有在Step6退出程序),输出“该矩阵不存在马鞍数”。任务5:马鞍数问题求解00#include<stdio.h>01#defineN502#defineM603intmain(){04intA[N][M]={{1,6,7,8,9,5},{4,5,6,7,8,6},{3,4,5,2,1,7},{2,3,4,9,0,8},{5,6,7,6,8,9}};05introwmin,colmax,i,k,m;06for(int(*prow)[M]=A;prow<A+N;prow++){//遍历每一行07 rowmin=9999;//行最小值,初始化为一个较大的数

08for(int*p=*prow;p<*prow+M;p++){//遍历当前行09if(*p<rowmin){10rowmin=*p;//记录较小数11k=p-*prow;//记录第i行最小值的列号k12}13}14 colmax=-9999;//列最大值,初始化为一个较小的数15for(int*p=A[0]+k;p<A[N-1]+M;p+=M){//重新遍历第k列16if(*p>colmax){17colmax=*p;//记录较大数18m=(p-A[0])/M;//记录第k列最大值的行号m19}20}21 if(rowmin==colmax){//当前行最小的数与对应列最大的数相同,马鞍数找到22 printf("马鞍数为%d,对应下标位置(%d,%d)\n",A[m][k],m,k);23 return0;//找到马鞍数,退出程序24 } 25 }26printf("该矩阵不存在马鞍数");27 return0; 28}任务1:指针基础(函数的输出参数)

任务2:变量数据交换

任务3:一维数组元素互换

任务4:字符串的插入

任务5:马鞍数

任务6:删除字符串中的空格

目录任务6:删除字符串中的空格内容概要1、任务描述2、相关知识3、设计思路4、问题求解任务6:删除字符串中的空格任务描述书写英文字符串时,由于手误,经常出现字符串前导空格、后置空格、单词之间多个连续空格的情况,例如“Howareyou”,这种情况不满足英文书写规范。本任务给定一个字符串,含有前导空格、后置空格、单词之间有多个连续空格,要求去除前导空格、后置空格,单词之间只保留一个空格,采用指针函数完成,在函数里面动态分配内存空间存储结果,函数返回结果字符串的首地址。任务6:删除字符串中的空格相关知识1、动态存储的分配与释放2、内存泄露问题3、函数指针任务6:删除字符串中的空格相关知识:动态内存(1)(1)分配内存空间:

使用malloc()函数分配指定字节数的内存空间:void*malloc(size_tsize);

使用calloc()函数分配指定数量和大小的内存空间,并将每个字节初始化为0:void*calloc(size_tnum,size_tsize);

使用realloc()函数重新分配指定内存块的大小:void*realloc(void*ptr,size_tsize);任务6:删除字符串中的空格相关知识:动态内存(2)(2)使用分配的内存空间:

将分配的内存空间用于存储数据,可以通过指针对其进行读取或写入操作。int*ptr=(int*)malloc(sizeof(int));*ptr=10;

注意,通过指针访问内存时要确保不会越界或空指针访问。(3)释放内存空间:

使用free()函数释放之前分配的内存空间:voidfree(void*ptr);

释放内存后,相应的指针将不再有效:int*ptr=(int*)malloc(sizeof(int));*ptr=10;free(ptr);//释放内存任务6:删除字符串中的空格相关知识:函数指针C语言函数指针是指向函数的指针变量。使用函数指针可以动态地调用不同函数,非常灵活。(1)定义函数指针变量:使用函数指针时,首先需要定义一个函数指针变量,指定函数的返回类型和参数类型:int(*ptr)(int,int);(2)初始化函数指针变量:将函数的地址赋值给函数指针变量。可以通过函数名直接给函数指针赋值。例如,对于函数intadd(inta,intb),可以通过以下语法初始化函数指针变量:ptr=add;(3)使用函数指针调用函数:通过函数指针变量可以调用相应的函数。使用函数指针调用函数时,可以像调用函数一样使用圆括号和参数列表。例如,使用函数指针调用add函数,可以使用以下语法:intresult=(*ptr)(3,4);任务6:删除字符串中的空格设计思路(拷贝规则)定义2个字符指针p1和p2,分别指向S1和S2的首元素规则1:若*p1的值不是空格,则一定拷贝规则2:若*p1的值是空格,但前一个字符不是空格,则该空格是单词和单词之间的空格,也应当进行拷贝w

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论