第六周编程总结

作业属于课程 C语言程序设计
作业要求 希望通过学习,学会使用指针
课程哪方面帮我实现目标 使用指针作为函数参数返回多个函数值
参考文献 https://edu.cnblogs.com/campus/zswxy/MS/homework/2893

一、作业

第一题

函数fun的功能是:求两数平方根之和,作为函数值返回。例如:输入12和20,输出结果是:y = 7.936238。

函数接口定义:
double fun (double *a, double *b); 
其中 a和 b是用户传入的参数。函数求 a指针和b 指针所指的两个数的平方根之和,并返回和。

实验代码

double fun (double *a,double *b)
{
	double z;
	
	z=sqrt(*a)+sqrt(*b);
  
	return z;
}

设计思路

第一步:定义函数
第二步:将题目中fun函数用sqrt表示
第三步:输出定义函数中的结果

本题调试遇到的问题及解决方法


问题:未看清题目,只要求写出定义函数部分,我写了整个函数,所以错误。
解决方法:看清题目

流程图

运行截图

完成时间

十分钟

第二题

读入n个整数,调用max_min()函数求这n个数中的最大值和最小值。

输入格式:
输入有两行: 第一行是n值; 第二行是n个数。

输出格式:
输出最大值和最小值。

输入样例:
在这里给出一组输入。例如:

5
8 9 12 0 3
输出样例:
在这里给出相应的输出。例如:

max = 12
min = 0

实验代码

#include<stdio.h>
void max_min(int n,int a[],int *pmax,int *pmin);
int main()
{
  int n,max,min,i;
  int a[100];
  int *pmax,*pmin;
  scanf("%d",&n);
  for(i=0;i<n;i++)
  {
    scanf("%d",&a[i]);
  }
  max_min(n,a,&max,&min);
  *pmax=max;*pmin=min;
  printf("max = %d\nmin = %d",*pmax,*pmin);
  return 0;
}

void max_min(int n,int a[],int *pmax,int *pmin)
{
  int i,j,temp;
  	for(i=0;i<n-1;i++)
	 {
	    for(j=0;j<n-1-i;j++)
	{
		if(a[j]<a[j+1])
	    {
		temp=a[j];
		a[j]=a[j+1];
		a[j+1]=temp;
	    }
    } 
}
  *pmax=a[0];
  *pmin=a[n-1];

设计思路

第一步:编译头文件
第二步:函数声明
第三步:定义变量
第四步:输入n,n个数
第五步:函数定义

本题调试遇到的问题及解决方法



问题:1、我第一次的思路不是此代码,是未使用指针的代码。
2、函数声明中我定义了两个变量,所以错误
3、各种粗心,少分号,逗号。
4、还是未得到解答,所以换了思路。
解决方法:仔细琢磨书上使用指针作为函数参数返回多个函数值的示例,加上和室友讨论,写出了代码。

流程图

运行结果截图

完成时间

一个多小时

第三题

为一维数组输入10个整数;将其中最小的数与第一个数对换,将最大的数与最后一个数对换;输出数组元素。。

函数接口定义:
void input(int *arr,int n);
void max_min(int *arr,int n);
void output(int *arr,int n);
三个函数中的 arr和n 都是用户传入的参数。n 是元素个数。

input函数的功能是输入 n个元素存到指针arr所指向的一维数组中。

max_min函数的功能是求指针arr所指向的一维数组中的最大值和最小值,其中最小的数与第一个数对换,将最大的数与最后一个数对换。

output函数的功能是在一行中输出数组元素,每个元素输出占3列。

实验代码

void input(int *arr,int n)
#include<stdio.h>
{
	int i;
	for(i=0;i<n;i++)
	scanf("%d",arr++);
}
void max_min(int *arr,int n)
{
	int max,min,i,t;
	for(i=0;i<n;i++)
	{
		if(arr[min]>arr[i])
		min=i;
		if(arr[max]<arr[i])
		max=i;
	}
  t=arr[min];
  arr[min]=arr[0];
  arr[0]=t;
  t=arr[max];
  arr[max]=arr[n-1];
  arr[n-1]=t; 
}
void output(int *arr,int n)
#include<stdio.h>
{
	int i;
	for(i=0;i<n;i++)
	{
		printf("%3d",arr[i]);
	}
}

设计思路

第一步:按照题目要求,input函数用for循环,遍历所有数
第二步:max_min函数找出最大和最小值,
第三步:output函数输出的每个元素占三列。

本题调试遇到的问题及解决方法


问题:1、scanf函数在#include<stdio.h>中,刚开始我未注意。
2、input函数需遍历元素,我未使arr++。
解决方法:思考,看书找出问题。

流程图

运行结果截图

完成时间

三十分钟

思考题

一、为什么要使用指针?它有什么用?
二、指针变量在内存中暂用多大的空间?它的大小由什么决定?

解答一、
1、在数据传递时,如果数据块较大(比如说数据缓冲区或比较大的结构),这时就可以使用指针传递地址而不是实际数据,即提高传输速度,又节省大量内存。
2.数据转换,利用指针的灵活的类型转换,可以用来做数据类型转换,比较常用于通讯缓冲区的填充,比如说,一个数据缓冲区char buf[100],如果其中buf[0,1]为命令号,buf[2,3]为类型,buf[4~7]为某一数值,类型为int,就可以使用如下语句进行赋值:
(short)&buf[0]=cmdID;
(short)&buf[2]=type;
(int)&buf[4]=value;
3.字符串指针,是使用最方便,且常用的。
4.函数指针,形如:#define PMYFUN (void*)(int,int),可以用在大量分支处理的实例当中,如某通讯根据不同的命令号执行不同类型的命令,则可以建立一个函数指针数组,进行散转。
5.在数据结构中,链表、树、图等大量的应用都离不开指针。
【资料来源(https://zhidao.baidu.com/question/1175237750949017619.html)】
2、指针的作用:
1、指针就是指向一个特定内存地址的一个变量。c语言指针可以有效地表示复杂的数据结构、动态分配内存、高效地使用数组和字符串、使得调用函数时得到多个返回值等。指针的应用往往与数组联系在一起,是最频繁的,也是最基础的。在定义数组和函数时,系统都会为其自动分配一个指向其首地址的指针。对于一个数组,其名称就是一个指针变量。
2、指针只是一个变量,它存储一个内存地址。如果传入一个地址,比传入一个struct效率要高,因为少了一个拷贝过程。
3、指针能够有效的表示数据结构,能动态分配内存,能较方便的使用字符串,有效的使用数组。
4、指针直接与数据等的储存地址有关,是比较重要的。比如,值传递不如地址传递高效,因为值传递先从实参的地址中提出值,再赋值给形参带入函数计算;而指针则把形参的地址直接指向实参地址,使用时直接提出数据,使效率提高,特别在频繁赋值等情况下。
【资料来源(https://wenwen.sogou.com/z/q805872897.htm)】
3、其实说C#和java里面不用指针,但处处是“指针”,里面不存在c++中的值传递,而是传递引用,而引用本质上就是指针。
为什么需要指针呢?由于c/c++开发先与java和c#,c/c++为了给程序员以控制内存的目的而提出了指针。
一个简单的例子就是垃圾回收机制。在c/c++中,你可以使用delete(free)来释放内存,在c#和java里面就只能靠其自己的内存回收机制来回收了。有些时候,内存吃紧的话是必须要立马释放的。那么这种情况c#和java就做不到了。
所以说c#和java里面不是不要指针,而是处处是“指针”,只是它给你封装了,不在让你头疼c/c++中指针带来的一些问题了。
【资料来源(https://wenwen.sogou.com/z/q873261172.htm)】
解答二、
1、教科书上说指针大小和机器字长相同,即32位机指针长度为4字节!但是对不对呢?为什么是这样?

  搜了一下相关资料。。。居然发现回答不统一,很多人也同样是糊里糊涂。

下面对这个问题做一个系统的整理和分析:

  首先,介绍几个基本概念:(主要摘自百度百科)

  字长:在同一时间中处理二进制数的位数叫字长。通常称处理字长为8位数据的CPU叫8位CPU,32位CPU就是在同一时间内处理字长为32位的二进制数据。二进制的每一个0或1是组成二进制的最小单位,称为一个比特(bit)。

  一般说来,计算机在同一时间内处理的一组二进制数称为一个计算机的“字”,而这组二进制数的位数就是“字长”。字长与计算机的功能和用途有很大的关系,是计算机的一个重要技术指标。字长直接反映了一台计算机的计算精度,为适应不同的要求及协调运算精度和硬件造价间的关系,大多数计算机均支持变字长运算,即机内可实现半字长、全字长(或单字长)和双倍字长运算。在其他指标相同时,字长越大计算机的处理数据的速度就越快。早期的微机字长一般是8位和16 位,386以及更高的处理器大多是32位。目前市面上的计算机的处理器大部分已达到64位。

  字长由微处理器(CPU)对外数据通路的数据总线条数决定。

  最小可寻址单位:内存的最小可寻址单位通常都是字节。也就是说一个指针地址值可对应内存中一个字节的空间。

  寻址空间:寻址空间一般指的是CPU对于内存寻址的能力。CPU最大能查找多大范围的地址叫做寻址能力,CPU的寻址能力以字节为单位 (字节是最小可寻址单位),如32位寻址的CPU可以寻址2的32次方大小的地址也就是4G,这也是为什么32位寻址的CPU最大能搭配4G内存的原因,再多的话CPU就找不到了。

  这里CPU的寻址位数是由地址总线的位数决定,32位CPU的寻址位数不一定是32位,因为32位CPU中32的意义为字长。

  有关寻址范围计算解释,对于32位寻址的CPU,其地址值为32位的二进制数,所以可以表示的最大地址为2的32次方(即4G,最大内存空间为4GB,这里G表示数量、GB表示容量)。同时我们不难看出,一个指针的值就是一个32位的二进制数,32位对应4字节(Byte)。所以,指针的大小实际上是由CPU的寻址位数决定,而不是字长。

再来分析一下如下的情况:

  32位处理器上32位操作系统的32位编译器,指针大小4字节。
  32位处理器上32位操作系统的16位编译器,指针大小2字节。
  32位处理器上16位操作系统的16位编译器,指针大小2字节。
  16位处理器上16位操作系统的16位编译器,指针大小2字节。

这从结果看起来指针的大小和编译器有关??

  实际不是这样的,有这样的结果是因为以上几种情况,处理器当前运行模式的寻址位数是不一样的,如下:

  Intel 32位处理器32位运行模式,逻辑寻址位数32,指针也就是32位,即4个字节
  Intel 32位处理器16位虚拟机运行模式,逻辑寻址位数16,指针也就是16位,即2个字节

  编译器的作用是根据目标硬件(即CPU)的特性将源程序编译为可在该硬件上运行的目标文件。如果一个编译器支持某32位的CPU,那么它就可以将源程序编译为可以在该CPU上运行的目标文件。该源程序中指针大小也会被编译器根据该CPU的寻址位数(如32位)编译选择为4字节。

  综上可得:指针大小是由当前CPU运行模式的寻址位数决定!
【资料来源(https://blog.csdn.net/lhj_168/article/details/80308041)】

二、学习进度条


三、描述结对编程的过程和结对编程的优缺点

过程:
优缺点:在我思考问题时,编程对象会主动提出帮助,我写代码,他输入代码,合作愉快,互帮互助。

学习感悟

1、看书很重要,明白怎样运用知识来写代码。
2、团结协作很重要,大家一起思考,共同完成作业。
3、好好学习,天天向上。

posted on 2019-04-04 00:12  彦页颜  阅读(387)  评论(1编辑  收藏  举报