2014-11-27 12:06:12 Bluecakeitsme 阅读数 3432
  • 征服C++ 11视频精讲

    扫码进入学习群,领取学习资料+讲师答疑 本教程是C++ Primer Plus 6th 、The C++ Programming Language_4th、Thinking in C++等国外顶级的C++著作的精华和个人超过10年的C++使用经验的完美结合。

    78389 人正在学习 去看看 李宁

今天帮同学调试一个程序,实验里面要求需要用函数返回一个二元数组,原本十分钟可以解决的问题花掉了很多时间。

实验要求是这样的:

1、矩阵(一)
编写C++程序完成以下功能:
(1)假定矩阵大小为4×5(整型数组表示);
(2)定义矩阵初始化函数,可以从cin中输入矩阵元素;
(3)定义矩阵输出函数,将矩阵格式化输出到cout;
(4)定义矩阵相加的函数,实现两个矩阵相加的功能,结果保存在另一个矩阵中;
(5)定义矩阵相减的函数,实现两个矩阵相减的功能,结果保存在另一个矩阵中;
(6)定义三个矩阵:A1、A2、A3;
(7)初始化A1、A2;
(8)计算并输出:A3 = A1加A2,A3 = A1减A2。


按照要求,addMatrix()、subMatrix()函数的输入为两个二维数组,同时返回一个二维数组

开始时尝试各种返回方式

int[][] addMatrix(int A1[][5], int A2[][5]))
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
            A[i][j]=A1[i][j]+A2[i][j];
    return A;
}

编译时报错

error: expected unqualified-id before '[' token

然后尝试了下面的写法

int*[] addMatrix(int A1[][5], int A2[][5]))
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
            A[i][j]=A1[i][j]+A2[i][j];
    return A;
}

编译时报错

error: expected initializer before '[' token

最后采用了下面一种写法

int** addMatrix(int A1[][5],int A2[][5])
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
            A[i][j]=A1[i][j]+A2[i][j];
    return (int**)A;
}

这一下可以编译通过,然后编写了下面一段测试程序:

#include <stdio.h>
#include <iostream>
using namespace std;

int** addMatrix(int A1[][5],int A2[][5])
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
            A[i][j]=A1[i][j]+A2[i][j];
    return (int**)A;
}
int main()
{
    int A1[][5]={{1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5}};
    int A2[][5]={{1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5}};
    int **A=addMatrix(A1,A2);
    for (int i=0;i<4;i++)
    {
        for (int j=0;j<5;j++)
            cout<<A[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}

虽然可以编译通过,但是在执行到cout语句时程序就会崩溃,在用visual调试的时候发现返回的地址并不能被访问,原理暂时不清楚,后面又百度到了下面的这种写法

#include <stdio.h>
#include <iostream>
using namespace std;

int (*addMatrix(int A1[][5],int A2[][5]))[5]
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
        {
            A[i][j]=A1[i][j]+A2[i][j];
            printf("%d %d %d \n",A[i][j],A1[i][j],A2[i][j]);
        }
    return A;
}

int main()
{
    int A1[][5]={{1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5}};
    int A2[][5]={{1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5}};
    int (*A)[5]=addMatrix(A1,A2);
    for (int i=0;i<4;i++)
    {
        for (int j=0;j<5;j++)
            cout<<A[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}

编译没有问题,运行也不会崩溃,但是结果全部是错的


通过调试可以看到,返回的数组类型为int[5]*,并不是我们需要的int*[5]。同时,通过汇编调试我们还可以看到,当程序在执行输出操作的时候,A地址所指向的数据会被改变,这不难理解,由于A地址的内存空间是我们在函数里面申请的,也就是说A数组属于局部变量,局部变量的数据存储在堆栈里面,当函数执行完毕后局部变量所占的内存就被释放掉,被释放并不意味着该地址所指向的空间的值会被清零,C++不会干这么没效率的事,释放只是告诉系统环境这一块区域可以再分配,这也就是为什么我们看到开始部分输出的数据是正确的,但是随着函数的重复调用,A地址指向的空间数据被新执行函数里面申请的局部变量所覆盖,所以得到的数据也变成了一些随机值。

综上所述,如果一定要通过函数来修改二维数组的话,可以通过参数的方式传入,或者通过结构体的形式返回,直接返回二维数组麻烦而且意义不大。

2017-09-29 19:58:40 tobe_numberone 阅读数 2914
  • 征服C++ 11视频精讲

    扫码进入学习群,领取学习资料+讲师答疑 本教程是C++ Primer Plus 6th 、The C++ Programming Language_4th、Thinking in C++等国外顶级的C++著作的精华和个人超过10年的C++使用经验的完美结合。

    78389 人正在学习 去看看 李宁
题目:

编写一个程序,用成员函数重载运算符“+”和“-”将两个二维数组相加和减,要求第一个二维数组的值由构造函数设置,另一个二维数组的值由键盘输入


用到的文件

maincpp.cpp

#define M 2
#include <iostream>
using namespace std;
#include "class.h"

int main()
{
	cout << "请输入4个数组成一个数组:\n";
	double arr[2][2];
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < M; j++)
		{
			cin >> arr[i][j];
		}
	}
	Array arr1;//自动设置二维数组
	Array arr2(arr);//传递二维数组
	Array arr3 = arr1 + arr2;//加
	Array arr4 = arr2 - arr1;//减

	cout << "arr3:" << endl;
	arr3.show();
	cout << "arr4:" << endl;
	arr4.show();
	system("pause");
	return 0;
}

class .h


#pragma once
class Array
{
public:
	Array();//自动设置二维数组的所有值为1
	Array(const double p[][M]);//用户传递一个二维数组
	Array operator+(Array &);//两个数组相加
	Array operator-(Array &);//两个数组相减
	void show();//显示数组
private:
	double a[M][M];
};
Array::Array()
{
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < M; j++)
		{
			a[i][j] = 1;
		}
	}
}
Array::Array(const double p[][M])
{
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < M; j++)
		{
			a[i][j] = p[i][j];
		}
	}
}
Array Array::operator+(Array &B)//采用了用成员运算符重载,可以利用this指针减少一个参数
{
	Array A1;
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < M; j++)
		{
			A1.a[i][j] = a[i][j]+B.a[i][j];//a[i][j]之所以不用指定对象,是因为this指针就指向“+”号的左操作数 
		}
	}
	return A1;
}
Array Array::operator-(Array &B)
{
	Array A1;
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < M; j++)
		{
			A1.a[i][j] =a[i][j] -B.a[i][j];
		}
	}
	return A1;
}
void Array::show()
{
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < M; j++)
		{
			cout << a[i][j]<<" ";
		}
		cout << '\n';
	}
}

运行结果:






2019-06-13 22:29:06 De_lovely_crane 阅读数 230
  • 征服C++ 11视频精讲

    扫码进入学习群,领取学习资料+讲师答疑 本教程是C++ Primer Plus 6th 、The C++ Programming Language_4th、Thinking in C++等国外顶级的C++著作的精华和个人超过10年的C++使用经验的完美结合。

    78389 人正在学习 去看看 李宁

编写一个程序,用成员函数重载运算符“+”和“-”,将两个二维数组相加和相减,要求第一个二维数组的值由构造函数设置,另一个二维数组的值由键盘输入

#include <iostream>
using namespace std;
#define m  2
#define n  3
class complex{
	public:
		complex ();
		complex (int a[m][n]);
		complex operator+(int b[m][n]);
		complex operator-(int b[m][n]);
		void show();
	private :
		int p[m][n];
}; 

complex::complex ()
{
	for(int i=0;i<m;i++)
		for(int j=0;j<n;j++)
		{
			p[i][j]=0;
		}
}

complex::complex (int a[m][n])
{
	for(int i=0;i<m;i++)
		for(int j=0;j<n;j++)
		{
			p[i][j]=a[i][j];
		}
}

complex complex::operator+(int b[m][n])
		{
			complex a;
			for(int i=0;i<m;i++)
				for(int j=0;j<n;j++)
				{
					a.p[i][j]=p[i][j]+b[i][j];
				}
			return a;
		}
complex complex::operator-(int b[m][n])
		{
			complex a;
			for(int i=0;i<m;i++)
				for(int j=0;j<n;j++)
				{
					a.p[i][j]=p[i][j]-b[i][j];
				}
			return a;
		}
		
void complex::show()
{
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<n;j++)
		{
			cout<<p[i][j]<<" ";
		}
		cout<<"\n";
	}
	
}
	
int main()
{
	int b[m][n]={{1,2,3},{4,5,6}};
	int x[m][n];
	complex d(b);
	complex aa;
	
	for(int j=0;j<m;j++)
		for(int i=0;i<n;i++)
		{
			cin>>x[j][i];
		}
	aa=d+x;
	aa.show();
	cout<<"\n";
	aa=d-x;
	aa.show();
	return 0;
}

友元函数完成二维数组加减重载

#include <iostream>
using namespace std;
#define m  2
#define n  3
class complex{
	public:
		complex ();
		complex (int a[m][n]);
		friend complex operator+(complex a ,int b[m][n]);
		friend complex operator-(complex a,int b[m][n]);
		void show();
	private :
		int p[m][n];
}; 

complex::complex ()
{
	for(int i=0;i<m;i++)
		for(int j=0;j<n;j++)
		{
			p[i][j]=0;
		}
}

complex::complex (int a[m][n])
{
	for(int i=0;i<m;i++)
		for(int j=0;j<n;j++)
		{
			p[i][j]=a[i][j];
		}
}

complex operator+(complex a,int b[m][n])
		{
			for(int i=0;i<m;i++)
				for(int j=0;j<n;j++)
				{
					a.p[i][j]=a.p[i][j]+b[i][j];
				}
			return a;
		}
complex operator-(complex a,int b[m][n])
		{
			for(int i=0;i<m;i++)
				for(int j=0;j<n;j++)
				{
					a.p[i][j]=a.p[i][j]-b[i][j];
				}
			return a;
		}
		
void complex::show()
{
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<n;j++)
		{
			cout<<p[i][j]<<" ";
		}
		cout<<"\n";
	}
	
}
	
int main()
{
	int b[m][n]={{1,2,3},{4,5,6}};
	int x[m][n];
	complex aa;
	complex d(b);
	
	for(int j=0;j<m;j++)
		for(int i=0;i<n;i++)
		{
			cin>>x[j][i];
		}
	aa=d+x;
	aa.show();
	cout<<"\n";
	aa=d-x;
	aa.show();
	return 0;
}

2019-01-10 08:49:29 qq_43090158 阅读数 1602
  • 征服C++ 11视频精讲

    扫码进入学习群,领取学习资料+讲师答疑 本教程是C++ Primer Plus 6th 、The C++ Programming Language_4th、Thinking in C++等国外顶级的C++著作的精华和个人超过10年的C++使用经验的完美结合。

    78389 人正在学习 去看看 李宁
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;

//矩阵运算的类
class Matrix
{
private:
	int row;//行
	int col;//列
	int **mat;//指向一级指针变量的二级指针,二级指针变量名可以看做二维数组的数组名
public:
	Matrix();
	Matrix(int r,int c);//构造函数
	Matrix(const Matrix &m);//拷贝构造函数
	
	friend Matrix operator+(Matrix &m1,Matrix &m2);//矩阵+矩阵

	friend istream & operator>>(istream &in,Matrix &ma);//重载>>输入运算符
	friend ostream & operator<<(ostream &out,Matrix &ma);//重载<<输出运算符
	~Matrix();//类中有动态申请数据空间,必须显式定义析构函数
};
Matrix::Matrix()
{
	row=0;
	col=0;
}
Matrix::Matrix(int r,int c): row(r),col(c)
{
	int i;
	mat=new int *[row];//动态创建二维数组
	for(i=0;i<row;i++)
		mat[i]=new int[col];//动态创建每一行上的每一列
}
Matrix::~Matrix()
{
	for(int i=0;i<row;i++)
		delete [] mat[i];
	delete [] mat;//先创建的后析构
}
//定义拷贝构造函数
Matrix::Matrix(const Matrix &m)
{	int i,j;
	row=m.row;
	col=m.col;
	mat=new int *[row];//动态创建二维数组
	for(i=0;i<row;i++)
		mat[i]=new int[col];//动态创建每一行上的每一列
	
	if(m.mat)
	{for(i=0;i<row;i++)
		for(j=0;j<col;j++)
			mat[i][j]=m.mat[i][j];
	}
}


//矩阵+矩阵
Matrix operator+(Matrix &m1,Matrix &m2)
{	Matrix m3(m1.row,m1.col);
	int i,j;
	if((m1.row==m2.row)&&(m1.col==m2.col))//判断两个矩阵是否为行数列数相同的矩阵,若是,就进行对应元素相加
	{
		for(i=0;i<m1.row;i++)
			for(j=0;j<m1.col;j++)
				m3.mat[i][j]=m1.mat[i][j]+m2.mat[i][j];
	}
	return m3;
}

istream &operator >>(istream &in,Matrix &ma)
{	int i,j;
	cout<<"Please input the Matrix:"<<endl;
	for(i=0;i<ma.row;i++)
	{
		cout<<"输入第  "<<i+1<<"  行:"<<endl;
		for(j=0;j<ma.col;j++)
			in>>ma.mat[i][j];
	}
	return in;
}
ostream &operator <<(ostream &out,Matrix &ma)
{	int i,j;
	cout<<"The Matrix is:"<<endl;
	for(i=0;i<ma.row;i++)
	{	for(j=0;j<ma.col;j++)
			out<<setw(5)<<ma.mat[i][j];
		cout<<endl;
	}
	return out;
}


int _tmain(int argc, _TCHAR* argv[])
{
	Matrix m1(2,3),m2(2,3);
	cin>>m1;
	
	cout<<m1;
	cin>>m2;
	cout<<m2;
	

	cout<<"m1+m2="<<m1+m2;
	

	return 0;
}

C++ | 重载 | 实验七

阅读数 114

没有更多推荐了,返回首页