数组和指针——拿来主义

关键知识

1.一维数组和二维数组数组的初始化以及定义以及理解

1.1一维数组的初始化以及定义以及理解

一维数组的定义——类型+数组名[];

一维数组的初始化——类型+数组名[]={};

一维数组的理解就是——定义一个具有相同类型的集合。(举例在下面)

int a[10];
//这个语句的意思就是创建一个一维数组,内含10个int类型的元素
#include<stdio.h>

#define MONTHS 12
//10.1打印12月,每一个月的天数
//好处:没有闪光点;
//优点(闪光点)

int main(void)
{
	int i;
	int month[12] = { 30,30,30,29,30,29,31,31,31,31,30,31 }; //初始化数组
  int year[15];//定义数组,但在这个函数中没用 

	for (i = 0; i < MONTHS; i++)
	{
		printf("这个%d月有 %d天\n",i+1, month[i]);
	}


	return 0;
}

1.2二维数组的定义以及初始化以及理解

二维数组的定义——类型名+数组名+[][];

二维数组的初始化——类型名+数组名+[][]={

{},

{}

}

二维数组的理解——两个数组之间在表示一个问题的时候有强烈的关系,这个时候就可以用二维数组,比如要分析5年内每一个月的降水量数据,就可以设置一个二维数组。

double a[2][3];
//意思就是内含2个数组元素的数组。其中每一个数组元素内含3个double类型的元素

#include <stdio.h>
#define MONTHS 12
#define years 5
//10.7;
// 输入是二维数组中的元素,输出为每年的总降水量,每年的平均降水量,5年中每月的平均降水量。
//闪光点:
int main(void)
{
	int year, month;
	float sum1, averageperyear, averagepermonth,sum2;
	const float array[5][12] = {// 在这里竟然有const数组,在239页,自己理解的const后面必须要初始化,否则很难const
	                            //还有一点就是float array[5][12]的意思就是内含5个数据元素的数组,其中每个数组元素内含12个float的元素。	
		{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},
		{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},//二维数组,更好区分
		{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},
		{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},
		{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},
	};
	//计算每年的总降水量,和每年的平均降水量
	for (year = 0; year < years; year++)
	{
		for (month = 0,sum1=0; month < MONTHS; month++)
		{
			sum1 = sum1 + array[year][month];
	}
		printf("第%d年的总输入量为%f\n", year+1, sum1);
		
	}
		printf("这%d年的平均输出量为%f\n", MONTHS , sum1/MONTHS);

	//5年中每月的平均降水量,提取a[][]
		for (month = 0; month < MONTHS; month++)
		{

			for (year = 0, sum2 = 0; year < years; year++)
			{

				sum2 = sum2 + array[year][month];
			}
			printf("五年中每%d月的平均输出量为%f\n",month+1,sum2/years);
		}


	return 0;

}

2.指针的定义,指向一维数组的指针和指向二维数组的指针

一般形式

指针的定义——int(要指向对象的数据类型)+ *+a(指针名字);

指向一维数组的指针:

int a[m];

int *b;

b=a;

指向二维数组的指针

int a[m][n];

int (*p)[n];//意思就是创建一个指向内含n个元素的数组

p=a;

2.1指针的定义以及指向一维数组的指针

#include<stdio.h>
//10.8;复习指针的基本操作以及使用方法
//闪光点:no
#define SIZE 5//定义寻找到5个指针的空间就停止了   

int main(void)
{
	int a[SIZE];
	int * p1;//指针的定义
	long b[SIZE];
	long * p2;
	int index;
	p1 = a, p2 = b;//指针指向一维数组
	printf("%23s %15s\n", "int a", "long b");
	for (index = 0;index < SIZE; index++)
	{
		printf("pointer+%d的地址为  %10p    long b所对应的是%10p\n",index,p1+index,p2+index);
		

	}

	return 0;
}

2.2关于指针中有些有趣的知识(不用记住)

#include<stdio.h>
//10.8;再次复习数组和指针的关系,没有闪光点
//闪光点:
#define size 5
int main(void)
{
	int i;
	int array[size] = { 31,25,25,25,25 };
	int* p;
	p = array;
	for (i = 0; i < size; i++)//这里使用指针来表示数组,个人觉得没必要记住,也没必要看,
	{
		printf("%d\n", *(p + i));//这里就只是为了说明*(p+i)==array[i];
	}
	return 0;
}

2.3指向二维数组的指针。

int a[m][n];
//在这里就是要注意一点就是
//1.a是二维数组的地址,包含m个数组元素的数组
//数组名都是表示地址的
//在a[m][n]中a是a[m]的数组名,它代表这a[m]的首地址
a[m]是a[m][n]的数组名,它代表着a[m][n]的首地址

#include <stdio.h>
//10.16就是二维数组的初始化 
//闪光点:没有闪光点 
int main(void)
{
	int a[3][2]={{2,3},{2,5},{2,6}};
	int (*pz)[2];//pz指向一个内含两个int类型值的数组
	//这里pz2的取值关键就是,一会代码敲出来就知道了。 
	pz=a; 
	printf("pz是%p, pz+1是%p\n",pz,pz+1);
	printf("pz[0]是%p,pz[0]+1是%p\n",pz[0],pz[0]+1);//pz[0]
	printf("*pz对应的值是%p,*pz对应的值加1是%p\n",*pz,*pz+1);//*pz
	printf("pz[0][0]是%p,pz[0][0]+1是%p\n",pz[0][0],pz[0][0]+1);//pz[0][0]
	printf("*pz[0]是%p,*pz[0]+1是%p\n",*pz[0],*pz[0]+1);//*pz[0]
	printf("**pz是%d,**pz+1是%d\n",**pz,**pz+1);//**pz
	//pz[2][1]
	
	
	
	return 0;
}

3.指针变量的基本运算

写出来这一段程序,指针变量的程序基本就会了。

#include <stdio.h>
int main(void)
{
     int urn[5] = { 100, 200, 300, 400, 500 };
     int * ptr1, *ptr2, *ptr3;

     ptr1 = urn;            // 把一个地址赋给指针
     ptr2 = &urn[2];        // 把一个地址赋给指针
                            // 解引用指针,以及获得指针的地址
     printf("pointer value, dereferenced pointer, pointer address:\n");
     printf("ptr1 = %p, *ptr1 =%d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1);

     // 指针加法
     ptr3 = ptr1 + 4;
     printf("\nadding an int to a pointer:\n");
     printf("ptr1 + 4 = %p, *(ptr1 + 4) = %d\n", ptr1 + 4, *(ptr1 + 4));
     ptr1++;                // 递增指针
     printf("\nvalues after ptr1++:\n");
     printf("ptr1 = %p, *ptr1 =%d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1);
     ptr2--;                // 递减指针
     printf("\nvalues after --ptr2:\n");
     printf("ptr2 = %p, *ptr2 = %d, &ptr2 = %p\n", ptr2, *ptr2, &ptr2);
     --ptr1;                // 恢复为初始值
     ++ptr2;                // 恢复为初始值
     printf("\nPointers reset to original values:\n");
     printf("ptr1 = %p, ptr2 = %p\n", ptr1, ptr2);
     // 一个指针减去另一个指针
     printf("\nsubtracting one pointer from another:\n");
     printf("ptr2 = %p, ptr1 = %p, ptr2 - ptr1 = %td\n", ptr2, ptr1, ptr2 - ptr1);
     // 一个指针减去一个整数
     printf("\nsubtracting an int from a pointer:\n");
     printf("ptr3 = %p, ptr3 - 2 = %p\n", ptr3, ptr3 - 2);

     return 0;
}

 

下面分别描述了指针变量的基本操作。 


1.赋值:可以把地址赋给指针。例如用数组名、带地址运算符(&)的变量名、另一个指针进行赋 值。在该例中把urn数组的首地址赋给了ptrl,该地址的编号恰好是0x7fff5fbff8dO。变量 ptr2获得数组utr的第3个元素(urri[2])的地址。注意,地址应该和指针类型兼容。也就是 说不能把double类型的地址赋给指向int的指针,至少要避免不明智的类型转换。099/011已 经强制不允许这样做。

2.解引用:*运算符给出指针指向地址上存储的值。因此,'pt ri的初值是180,该值存储在编号为 Ox7fff5Fbff8d。的地址上。 ・取址:和所有变量一样,指针变量也有自己的地址和值。对指针而言&运算符给出指针本身的地 址。本例中,ptrl存储在内存编号为。x7ffFSfbFf8cB的地址上,该存储单元存储的内容是 Ox7FffSFbffBd。即urn的地址。因此&ptrl是指向ptrl的指针而pt r 1是指向 utn[0〕的指针。

3.指针与整数相加:可以使用+运算符把指针与整数相加,或整数与指针相加。无论哪种情况,整数 都会和指针所指向类型的大小(以字节为单位)相乘,然后把结果与初始地址相加。因此ptrl + 4 与&urn{4]等价。如果相加的结果超出了初始指针指向的数组范围计算结果则是未定义的。除非正好超过数组末尾第一个位置 C保证该指针有效。

4.递增指针:递增指向数组元素的指针可以让该指针移动至数组的下一个元素。因此,ptrl十十相当于 把pt r 1的值加上4(我们的系统中,nt为4字节),ptr'l指向。rri[1](现在ptrl的值是0x7ffFSfbFf8d4(数组的下一个元素的地址),* Pt。的值为200(即urn[J.〕的值)。注意ptrl本身的地址仍是0x7Fff5Fbff8c8。毕竟, 变量不会因为值发生变化就移动位置。 
 

5指针减去一个整数:可以使用-运算符从一个指针中减去一个整数。指针必须是第1个运算对象,整 数是第2个运算对象。该整数将乘以指针指向类型的大小(以字节为单位),然后用初始地址减去乘 积。所以Ptr3-2与&urn[2〕等价,因为ptr3指向的是&urn[4]。如果相减的结果超出了初始指针所指向数组的范围计算结果则是未定义的。除非正好超过数组末尾第一个位置C保证该指针 有效。

6.递减指针:当然,除了递增指针还可以递减指针。在本例中递减ptr2使其指向数组的第2个元素 而不是第3个元素。前缀或后缀的递增和递减运算符都可以使用。注意在重置ptrl和pt r2前 它们都指向相同的元素。rn[1] 

7.指针求差:可以计算两个指针的差值。通常,求差的两个指针分别指向同一个数组的不同元素通过计 算求出两元素之间的距离。差值的单位与数组类型的单位相同。例如,程序清单10.13的输出中 ptr2一ptr1得2意思是这两个指针所指向的两个元素相隔两个int:而不是2字节。只要两个指针都指向相同的数组(或者其中一个指针指向数组后面的第1个地址)C都能保证相减运算有效。如果指向两个不同数组的指针进行求差运算可能会得出一个值或者导致运行时错误。

8.・比较:使用关系运算符可以比较两个指针的值前提是两个指针都指向相同类型的对象。 
 

以上是官方解释,但基本上用到的很少,在这里就解释常见的两个——1.指针+一个整数和2.指针递减,

这里就以一维数组为例。

int *p;
int a[n];
p=a;
//这时候p+1就是a[1]的地址
//p++也是a[1]的地址
//另外p++遇到循环的时候p++就是指向数组下一个的元素

4.指针在调用数组作为参数的函数调用和函数原型

ps最重要的:当函数用指针的时候

基本上就记住一点:函数调用的时候用的是——地址

函数原型的时候用的是——指针(对于数组来说又另外一种表达方式——数组表示方法)

4.1 指针作为调用一维数组作为参数的函数原型以及函数

1.函数调用——doubleprint(array);

2.函数原型——void doubleprint(const double array[])//数组表示方法

或者——void doubleprint(double *p)//指针表示方法

参考代码

//10.14;实现两个函数,一个函数让数组的每一个值都乘以一个给定的值,一个函数实现输出原来的数组
//闪光点:const函数,感觉其实没有闪光点const.个人觉得有一个注意事项。如果定义const数组1,没有const数组2,const指针1,没有const指针2
//指针1可以指代数组1和数组2,指针2只能指向数组2;就很扯。下文由于没有用到指针,所以上面闪光点与下位代码无关 
#include <stdio.h>
#define square 2
#define size 5
void doublesquare(double array[]);//函数声明
void doubleprint(const double array[]);

int main(void)
{
	int i;
	double array[5] = { 23.2,23.2,25.2,24.2,27.2 };
	doubleprint(array);//函数调用
	doublesquare(array);
	printf("经过乘以一个固定值之后的数组\n");
	for (i = 0; i < size; i++)
	{
		printf("%8.3lf", array[i]);
	}
	return 0;

}
void doubleprint(const double array[])
{
	int i;
	printf("这是原来数组输出的值\n");
	for (i = 0; i < size; i++)
	{
		printf("%8.3lf", array[i]);
	}
	printf("\n");
}

void doublesquare(double array[])
{

	int i;
	for (i = 0; i < size; i++)
	{
		array[i] = array[i] * square;
		printf("%8.3lf", array[i]);
	}
	printf("\n");
}

4.2指针作为调用二维数组作为参数的函数原型以及函数

函数调用:

linessum(a);
   rowsssum(a);

函数原型:

void linessum(int array[][lines]);
  void rowsssum(int array[][lines]);
  void linessum2(int(*p)[lines]);

另外二维数组想要调用其一维数组的内容时候:

如a[m][n]想要a[m]进入函数里面,那么调用函数应为(a[m])//因为a[m]就是地址。详情见前面分析或者后面的编程练习


//10.17;问题就是先设计一个二维数组,然后设计两个函数,可以计算二维数组中每一行的总和。以及每一列的总和以及全部二维数组的总和 
//闪光点:
#define rows 3
#define lines 4
void linessum(int array[][lines]);
  void rowsssum(int array[][lines]);
  void linessum2(int(*p)[lines]);


int main(void)
{
	
	int a[rows][lines]={
	{2,4,5,6},
	{1,2,3,5},
	{2,7,8,9}
	};
	
	linessum(a);
	rowsssum(a); 
	
	return 0;
 } 
 void linessum(int array[][lines])
 //上面是数组标志方式

 下面是指针表示方法 
//void linessum2(int (*p)[lines])
  
 
 //输出第n个一维数组的和
 //这会报错,  void linessum(array[][])//
 //官方解释是因为不知道指针指向的数组类型,就无法操作
 //并且自己蠢到 没有给数组array[] int
  
 {
 	int sum,i,j;
 	
 	for(i=0;i<rows;i++)
 	{
 		sum=0;
 		printf("%d行的和是      ",i+1);
 		for(j=0;j<lines;j++)
 		{
 			sum=sum+array[i][j];
		 }
		 printf("%d\n",sum);
	 }
 	
 	
 	
 }
 
  void rowsssum(int array[][lines])//输出第n个一维数组的和
 //这会报错,  void linessum(array[][])//
 //官方解释是因为不知道指针指向的数组类型,就无法操作
 //并且自己蠢到 没有给数组array[] int
  
 {
 	int sum,i,j;
 	
 	for(j=0;j<lines;j++)
 	{
 		sum=0;
 		printf("%d列的和是      ",j+1);
 		for(i=0;i<rows;i++)
 		{
 			sum=sum+array[i][j];
		 }
		 printf("%d\n",sum);
	 }
 }
 

巧妙的解法

#include <stdio.h>
//10.4;
//闪光点:1.当array[]没有设置值的时候,编译器会根据其初始化列表中的数来计算。
//2.sizeof()可以计算数组的运算对象大小
int main(void)
{
	int i;
	int array[] = { 20,10,30,40 };
	for (i = 0; i < sizeof(array) / sizeof(array[0]); i++)//巧妙地解法
	{
		printf("这个%d月大概有%d天\n", i + 1, array[i]);
	}


	return 0;
}

(用作参考)课后习题答案:

由于自己用的是c primer plus教材,所以写的是c primer plus的参考答案.

注意:每一道题:自己都没有添加#include <stdio.h>.如果使用的话,记得填上。并且要分开运行。

#include <stdio.h>
// 编程练习
//10.13.1;将10.7的内容化为指针进行计算
//闪光点:
//  10.7
// 输入是二维数组中的元素,输出为每年的总降水量,每年的平均降水量,5年中每月的平均降水量。由于书中没有教如何将
// 二维数组放在主函数进行操作,所以就只能通过创建函数来解决这个问题
//闪光点:
#define MONTHS 12
#define years 5
void cirperyearwater(double array[][MONTHS]);
void cirperyearwater2(double(*p)[MONTHS]);

int main(void)
{
	int year, month;
	double array[5][12] = {// 在这里竟然有const数组,在239页,自己理解的const后面必须要初始化,否则很难const
		//还有一点就是float array[5][12]的意思就是内含5个数据元素的数组,其中每个数组元素内含12个float的元素。	
{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},
{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},//二维数组,更好区分
{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},
{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},
{4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3,4.3},
	};

	cirperyearwater(array);
	cirperyearwater2(array);

	return 0;
}
	void cirperyearwater(double array[][MONTHS])
	{
		int year, month;
		double sum1=0;
		for (year = 0; year < years; year++)
		{
			for (month = 0, sum1 = 0; month < MONTHS; month++)
			{
				sum1 = sum1 + array[year][month];
			}
			printf("第%d年的总输入量为%f\n", year + 1, sum1);

		}
		printf("这%d年的平均输出量为%f\n", MONTHS, sum1 / MONTHS);





	}

	//计算每年的总降水量,和每年的平均降水量
	void cirperyearwater2(double (*p)[MONTHS])
	{
		int year, month;
		double sum1 = 0;
		for (year = 0; year < years; year++)
		{
			for (month = 0, sum1 = 0; month < MONTHS; month++)
			{
				sum1 = sum1 + p[year][month];
			}
			printf("第%d年的总输入量为%f\n", year + 1, sum1);

		}
		printf("这%d年的平均输出量为%f\n", MONTHS, sum1 / MONTHS);





	}


// 编程练习10.13 .2
void copy_ptrs(double* p1, double* p2, double* p);
void printarray(double array[], int size);
void copy_arr(double target[], double source[], int size);
void copy_ptr(double* p1, double* p2, int size);
// 闪光点:
//指针的运算
//(这一切关于指针的运算都有一个前提条件就是必须指向同一个类型.):
//1.指针加上或者减去一个整数亦或者递增和递减.比如a是一个指针,指向数组中的首地址a[0].a+2就是a[2].a++就是指向下一个a[1]
//2.指针之间相加,或者相减.所得到的就是2个元素之间的距离.比如;a,b都是一个指针,a指向a[0],b指向a[2].他们的差就是2.意思是
//两个指针之间相差2个int类型.
int main(void)
{
	double source[5] = { 1.1,2.2,3.3,4.4,5.5 };
	double target1[5];
	double target2[5];
	double target3[5];
	copy_arr(target1, source, 5);
	copy_ptr(target2, source, 5);
	copy_ptrs(target3, source, source + 5);
	//建立一个输出函数。进行结果分析
	printarray(target1, 5);
	printf("\n");
	printarray(target2, 5);
	printf("\n");
	printarray(target3, 5);

	

	return 0;
}
void printarray(double array[],int size)
{
	int i;
	for (i = 0; i < size; i++)
		printf("%5.2lf", array[i]);
	
}



void copy_arr(double target[], double source[], int size)//带数组的表示方法
{
	int i;
	for (i = 0; i < size; i++)
		target[i] = source[i];


}

void copy_ptr(double *p1, double *p2, int size)//带指针的和带指针递增的方法
{
	int i;
	for (i = 0; i < size; i++)
	{
		*(p1 + i) = *(p2 + i);
	}
	
}

void copy_ptrs(double *p1, double *p2, double * p)//最后一个是指向源数组最后一个元素的指针
{
	int i,size;
	size = p - p2;
	for (i = 0; i <size ; i++)
	{
		*(p1 + i) = *(p2 + i);
	}
}


//编程练习10.13.3
int returnarraymax(int array[], int size);
int main(void)
{
	int array[5] = { 1,52,36,84,22 };
	
	printf("%d", returnarraymax(array, 5));

	return 0;
}
//返回一个数组中的最大值
int returnarraymax(int array[],int size)
{
	int max=0,i;
	for (i = 0; i < size; i++)
	{

		if (array[i] > max)
			max = array[i];
	}
	return max;

}


//编程练习10.13
//第4题//返回在数组中取得最大值的坐标
int returnarraymaxi(double array[], int size);
int main(void)
{

	double array[5] = { 12.2,15.2,20.5,16.0,19.2 };
	printf("数组a中最大值所对应的下标为%d", returnarraymaxi(array, 5));



	return 0;
}

int returnarraymaxi(double array[], int size)
{
	int h,i;
	double max=array[0];
	for (i = 0; i < size; i++)
	{
		if (array[i] > max)
		{
			max = array[i];
			h = i;

		}


	}

	return h;

}




//编程练习10.13
//第5题:编辑一个函数,使其返回数组中最大值与最小值的差值
double returnmaxsubmin(double array[], int size);
int main(void)
{

	double array[5] = { 12.2,15.2,20.5,16.0,19.2 };
	printf("数组a中最大值sub最小值所对应的值为%lf\n", returnmaxsubmin(array, 5));



	return 0;
}

double returnmaxsubmin( double array[],int size)
{
	double min, max;
	int i;
	min = max = array[0];
	for (i = 0; i < size; i++)
	{
	
		if (min > array[i])
		{

			min = array[i];
		}
		if (max < array[i])
		{
			max = array[i];
		}

		
	}

	return max - min;
}



//编程练习10.13第6题
//编辑一个函数,使其将原来数组倒序输出;

void printarray(const double array[], int size);
void reverseprint(double a[], int size);
int main(void)
{

	double array[5] = { 12.2,15.2,20.5,16.0,19.2 };
	printarray(array, 5);
	printf("\n");
	reverseprint(array, 5);
	printf("\n");
	printarray(array, 5);

	return 0;
}

//打印数组


void printarray(const double array[], int size)
{
	int i;
	for (i = 0; i < size; i++)
	{
		printf("%5.1f", array[i]);

	}
}
void reverseprint(double a[], int size)
{
	int i;
	double t;
	//倒序输出我会,但是倒序排列
	//运用数学知识
	for (i = 0; i < size/2; i++)//我的妈呀,这里的数组排序就不应该关键就是size/2.否则会一直循环到最后。
	{
		t = a[i];
		a[i] = a[size - 1 - i];
		a[size - 1 - i] = t;
	}

}


//编程练习10.13
//第7题
//编写一个程序
#define lines 3
#define rows 2;
void copy_source(double source[][lines], double dest[][lines], int size);
void printarray(double array[][lines], int size);
//初始化一个double的二维数组,然后利用copy函数将一个 数组复制到另一个数组里
int main(void)
{
	double a[2][lines] = {
		{2.5,2.7,2.9},
		{2.6,2.1,2.3}
	};
	double b[2][lines];
	printarray(a, 2);
	copy_source(a, b, 2);
	putchar('\n');
	printarray(b, 2);



	return 0;
}
//打印二维数组的函数
void printarray(double array[][lines],int size)
{
	int i, j;
	for (i = 0; i < size; i++)
	{
		for (j = 0; j < lines; j++)
		{
			printf("%5.1f", array[i][j]);
		}
		putchar('\n');
	}


}
//实现复制数组的函数
void copy_source(double source[][lines], double dest[][lines], int size)
{
	int i, j;
	for (i = 0; i < size; i++)
	{
		for (j = 0; j < lines; j++)
		{
			dest[i][j] = source[i][j];


		}
	}
}




//编程练习10.13
//第8题就是让一个数组中的第3-第5个元素拷贝到内含3个元素的数组
void printarray(double array[], int size);
void copyarray(double* p, double dest[], int size);

int main(void)
{
	double source[7] = { 1.1,2.2,3.3,4.4,5.5,6.6,7.7 };
	double target1[3];

	printarray(source, 7);

	copyarray(&source[2], target1, 3);
	putchar('\n');
	printarray(target1, 3);

	return 0;
}


void copyarray(double* p,double dest[], int size)
{
	int i;
	for (i = 0; i < size; i++)
	{
		dest[i] = *p;
		p++;
	}


}

void printarray(double array[],int size)
{
	int i;
	for (i = 0; i < size; i++)
		printf("%5.2lf", array[i]);
}



//编程练习10.13
//第9题:变长数组
void transe(double a[], double b[], double source[], int size);
void printarray(double a[], int size);
#define rows 4;
int main(void)
{
	double array[4] = { 2,4,5,8 };
	double b[4] = { 1,0,4,6 };
	double c[4];
	transe(array, b, c, 4);
	printarray(array, 4);
	putchar('\n');
	printarray(b, 4);
	putchar('\n');
	printarray(c, 4);


	return 0;
}
void printarray(double a[], int size)
{
	int i;
	for (i = 0; i < size; i++)
		printf("%5.1f",a[i]);


}

void transe(double a[], double b[], double source[], int size)
{
	int i;
	for (i = 0; i < size; i++)
	{
		source[i] = a[i] + b[i];
	}



}


//编程练习10.13
// 
 /*闪光点:就是需要定义一个rows。否则浪费我一个小时来改成这个bug;
 以后凡是涉及到二维数组都要进行rows的定义。*/
#define cols 5
#define rows 3
void exportarray(int a[][cols], int size);
void multarray(int array[][cols], int size);
//第11题:编写两个函数,一个函数原样输出二维数组,一个函数让二维数组的值都乘以2倍。
int main(void)
{
	int array[3][cols] =
	{
		{2,3,4,5,5},
		{1,2,3,4,2},
		{2,5,3,6,7}
	};
	exportarray(array, 3);
	multarray(array, 3);
	putchar('\n');
	exportarray(array, 3);

	return 0;
}
//原样输出该数组的值-单独运行的时候没有问题
void exportarray(int a[][cols], int size)
{
	int i, j;
	for (i = 0; i < size; i++)
	{
		for (j = 0; j < cols; j++)
			printf("%5d   ", a[i][j]);
		putchar('\n');
	}
	return;
}

//将原数组的值全部乘以2,
void multarray(int array[][cols], int size)
{
	int i, j;
	for (i = 0; i < size; i++)
	{
		for (j = 0; j < cols; j++)
			array[i][j] = 2 * array[i][j];
	}
	return;
}





//编程练习10.13
// 输入,用户输入三组数,每组数中都有5个元素,
// 任务就是编辑每一个单独的函数:
// 1.将这些数字存储到3*5的数组中。
// 2.计算每组数的平均值(设计一个计算一维数组的平均值,然后利用循环调用这个函数3次)
//  3.计算出所有数字的平均值
//  4.找出这15个数据中的最大值(将这个数组作为参数)3和4需要将结果送到主函数里面
// 5.打印结果
// 闪光点
//第11题

#define rows 3
#define lines 5
void exportarray(double array[][lines], int row);
void storearraylines(double array[], int line);
double averagearray(double array[], int line);
int main(void)
{
	int row;
	double array[rows][lines];
	printf("请输入3组数字,其中每组数字都包含5个数字\n");
	for (row = 0; row < rows; row++)
	{
		printf("请输入第%d组数字\n",row+1);
		storearraylines(array[row], lines);	
	}
	exportarray(array, rows);

	//计算出每组数的平均值
	for (row = 0; row < rows; row++)
	{
		printf("第%d组的平均值是%5.1lf\n", row + 1, averagearray(  array[row], 5));//这应该算的是闪光点。下面的函数不用写了,把 这个弄懂就行了1.二维数组调用一维数组的函数的时候,实参和形参分别是什么?2.二维数组调用二维数组的时候,实参和形参分别是什么
		//3.一维数组调用函数的时候,实参和形参分别是什么?

		//先解决出来第一个问题就是1.假设a[m][n]是一个二维数组。a[0]对于一维数组a[0][0]来说是一维数组的地址,又是二维数组的第一个的元素。

	}


	return 0;
}
//计算出每组数的平均值,有要求,就是设计出计算一维数组的平均值,然后循环调用这个函数三次
double averagearray(double array[],int line)
{
	int i;
	double average1,sum=0;
	for (i = 0; i < line; i++)
	{
		sum = sum + array[i];
	}
	average1 = sum / line;
	return average1;
}



void exportarray(double array[][lines], int row)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < lines; j++)
		{
			printf("%5.1lf", array[i][j]);

		}
		putchar('\n');
	}

}

void storearraylines(double array[], int line)
{
	int j;
	for (j = 0; j < line; j++)
	{
		printf("请输入数字 #%d:", j + 1);
		scanf("%lf", & array[j]);

	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正在变秃的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值