C++练习一

1、请声明一个类来存储时间。

 私有成员变量包括:m_iHour,m_iMin,m_iSec。公有成员函数包括:void set(int aHour, int aMin, int aSec)

void display(void)。

#include <iostream>

using namespace std;

//定义一个时间类
class Time
{
    private:
        int m_iHour;
        int m_iMin;
        int m_iSec; 
    public:
        void set(int aHour, int aMin, int aSec)
        {
            this->m_iHour = aHour;
            this->m_iMin = aMin;
            this->m_iSec = aSec;
        }

        void display(void)
        {
            cout << m_iHour << ":" << m_iMin << ":" << m_iSec << endl;
        }
};

int main()
{
    //定义一个时间类的对象
    Time t;
    //设置时间
    t.set(19,45,29);
    t.display();

    return 0;
}

编译运行:

2、请声明一个类来存储空间中的点。

私有成员包括:m_dX,m_dY。公有成员函数包括:void set(double aX, double aY)

double getX(void)

double getY(void)

#include <iostream>

using namespace std;

//定义一个点类
class Poin
{
    private:
        double m_dX;
        double m_dY; 
    public:
        void set(double aX, double aY)
        {
            this->m_dX = aX;
            this->m_dY = aY;
        }

        double getX(void)
        {
            return m_dX;
        }

        double getY(void)
        {
            return m_dY;
        }
};

int main()
{
    //定义一个点类的对象
    Poin a;
    //设置时间
    a.set(100,200);
    
    //获取点的数据
    cout << "X: " << a.getX() << endl;
    cout << "Y: " << a.getY() << endl;

    return 0;
}

编译运行:

3、设计一个简单的关于类的程序。

定义一个点类,包含x、y坐标,包含以下功能:

(1)设置x坐标

(2)设置y坐标

(3)得到x坐标

(4)得到y坐标

练习目的:

(1)类的定义方法、实例化的方法

(2)使用构造函数和析构函数

(3)类成员访问控制的运用

(4)体会面向对象程序设计方法

#include <iostream>

using namespace std;

class Poin
{
    private:
        int x;
        int y;

    public:
        Poin(){}    //默认构造
        Poin(int x,int y):x(x),y(y){}    //带参构造函数,用参数列表初始化方式初始化
        ~Poin(){}    //析构函数
        
        //设置点
        void set_x(int x)
        {
            this->x = x;
        }

        void set_y(int y)
        {
            this->y = y;
        }

        //获取点
        int get_x(void)
        {
            return x;
        }

        int get_y(void)
        {
            return y;
        }
};

int main()
{
    //定义一个点类对象
    Poin a(10,20);
    cout << "x: " << a.get_x() << endl;
    cout << "y: " << a.get_y() << endl;

    //设置点的位置
    a.set_x(123);
    a.set_y(456);

    cout << "x: " << a.get_x() << endl;
    cout << "y: " << a.get_y() << endl;

    return 0;
}

编译运行:

4、设计一个lcd设备类如下:

class LcdDevice
{
    public:
        LcdDevice(const char *device="/dev/fb0");
        ~LcdDevice();
        void open(const char *device="/dev/fb0");
        void close();
        void draw_point(int x,int y);
        void draw_line(int x,int y,int x2,int y2);
        void draw_rect(int x,int y,int w,int h);
    private:
        bool isOpen;
        int fd;
        unsigned int *mmp;
        int width;
        int height;
        int pixel;
        unsigned long memsize;    //一整屏显示所需要的内存空间
}

实现上面函数并且写一个main函数测试lcd设备类。

#include <iostream>
#include <iomanip>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <math.h>

#include <sys/types.h>	//open
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/mman.h>	//mmap

using namespace std;

//像素颜色
#define RED		0x00ff0000
#define GREEN	0x0000ff00
#define BLUE	0x000000ff
#define BLACK	0x00000000
#define YELLOW	0x00ffff00
#define WHITE	0x00ffffff

int diameter = 6;	//点的直径(像素点数)

class LcdDevice
{
    public:
		//构造函数
        LcdDevice(const char *device="/dev/fb0",int width = 800,int height = 480):LCD_width(width),LCD_height(height)
		{
			this->memsize = this->LCD_height * this->LCD_width * 4;
			this->pixel = 4;	//描述色深(位深)
			
			open_LCD(device);
		}
		
		//析构函数
        ~LcdDevice()
		{
			close_LCD();
		}
		
		//打开显示屏文件 且 映射
        void open_LCD(const char *device="/dev/fb0")
		{
			//打开显示屏文件
			this->fd = open(device,O_RDWR);
			if(fd == -1)
			{
				cout << "显示屏文件打开错误:" << endl;
				perror("");
				isOpen = false;
				return;
			}
			//内存映射
			this->mmp = (unsigned int *)mmap(NULL, //你要映射的内存空间的起始地址,为NULL系统自动给你分配
						memsize,//你要映射的内存空间的大小
						PROT_READ|PROT_WRITE,//映射的权限 
						MAP_SHARED,//1、进程共享  2、对应的文件会同步发生变化 	
						fd,//映射液晶屏文件
						0//偏移量 ,默认为0
						);
						
			if(this->mmp == NULL)
			{
				cout << "内存映射失败:" << endl;
				perror("");
				isOpen = false;
				return;
			}
			
			isOpen = true;
		}
		
		//关闭显示屏
        void close_LCD()
		{
			//接触映射
			munmap(this->mmp,memsize);
			//关闭显示屏文件
			close(this->fd);
			
			this->mmp = NULL;
			this->fd = -1;
			isOpen = false;
		}
		
		//全屏白色
		void full_White()
		{
			int i,j;
			for(i = 0; i < LCD_height; i++)
			{
				for(j = 0; j < LCD_width; j++)
				{
					this->mmp[i * LCD_width + j] = WHITE;
				}
			}
		}
		
		//画点 x y 位置  color 颜色
        void draw_point(int x,int y,int color)
		{
			int i,j,d,str;
			//加粗点
			for(i = y - diameter / 2; i < y + diameter / 2; i++)
			{
				if(i >= LCD_height || i < 0)
				{
					continue;
				}
				
				d = abs((diameter / 2 * diameter / 2) - ((y - i)*(y-i)));
				str = sqrt(d);	//弦长一半
				
				//正在画点
				for(int j = x - str; j < x + str; j++)
				{
					if(j >= LCD_width || j < 0)
					{
						continue;
					}
					
					this->mmp[i * LCD_width + j] = color;
				}
			}
		}
		
		//画直线
		//需要用到两点间的直线公式
        void draw_line(int x1,int y1,int x2,int y2,int color)
		{
			int i,j;
			
			//判断线的方向
			if(x2 < x1)
			{
				x1 = x1 + x2;
				x2 = x1 - x2;
				x1 = x1 - x2;
				
				y1 = y1 + y2;
				y2 = y1 - y2;
				y1 = y1 - y2;
			}
			
			float slope;	//直线斜率
			
			if(x2 - x1 != 0)
			{
				slope = (y2 - y1) * 1.0 / (x2 -x1);
				
				for(i = x1; i < x2; i++)
				{
					draw_point(i,(int)((i - x1)*slope + y1),color);
				}
			}
			else	//斜率无穷大
			{
				if(y2 < y1)
				{
					y1 = y1 + y2;
					y2 = y1 - y2;
					y1 = y1 - y2;
				}
				for(j = y1; j < y2; j++)
				{
					draw_point(x1,j,color);
				}
			}
		}
		
		//画矩形
        void draw_rect(int x,int y,int w,int h,int color)
		{
			draw_line(x, y, x+w, y, color);
			draw_line(x, y, x, y+h, color);
			draw_line(x, y+h, x+w, y+h, color);
			draw_line(x+w, y, x+w, y+h, color);
		}
    private:
        bool isOpen;			//判断显示屏文件是否打开
        int fd;					//显示屏文件描述符
        unsigned int *mmp;		//映射内存地址
        int LCD_width;			//显示屏宽度
        int LCD_height;			//显示屏高度 
        int pixel;				//一个像素点所占的字节
        unsigned long memsize;  //一整屏显示所需要的内存空间(LCD_height*LCD_width*4)
};

int main()
{
	LcdDevice a;
	
	a.full_White();
	a.draw_line(0, 240, 800, 240, RED);	//斜率等于0
	a.draw_line(400, 0, 400, 480, RED);	//斜率无穷大
	a.draw_line(0, 0, 800, 480, RED);		//斜率大于0
	a.draw_line(800, 0, 0, 480, RED);		//斜率小于0
	
	a.draw_rect(80, 60, 80*8, 60*6, RED);
	
	return 0;
	
}

5、class 和 struct 有什么区别

1、class可以设置数据成员属性,结构体不可以

2、class有构造函数、析构函数,结构体没有

3、class可以继承,结构体不可以

4、class可以实现多态,结构体不可以

6、看代码写结果(考点:类对象的私有成员函数不能用对象访问。)

以下代码哪里有错(C):

#define public private    //(1)    把public宏定义为private

class Animal
{
    public:                //(2)    替换成了private
        void MakeNoise();
};

int main()
{
    Animal animal;
    animal.MakeNoise();    //(3)    错误的,私有成员不可以通过对象直接访问
    return 0;
}

A、(1)        B、(2)        C、(3)        D、(2)(3)

7、找错(类成员的初始化)

考点:初始化列表的构造顺序

#include <iostream>
using namespace std;

class Obj
{
    public:
        Obj(int k):j(k),i(j)    //想要的结果是:j = k, i = j
        {
            //j = k, i = j 这两句谁先执行呢?
            //思考可能有以下两种情况:
            //情况1:j = k 先执行,i = 2, j = 2
            //情况2:i = j 先执行,i = 随机值, j = 2
   
            //实际上,是第二种情况
            //那么将参数列表填写顺序改变:Obj(int k):i(j),j(k),事实上,还是会执行第二种情况
            //同时,哪句先执行,与参数列表的填写顺序无关!!
        }
        void print(void)
        {
            cout << i << endl << j << endl;
        }
    private:
        int i;    //类中的成员空间分配, 是从 上 往 下 的,所以是 i 先分配,再分配 j,i就是随机值!!
        int j;
};

int main(int argc, char *argv[])
{
    Obj obj(2);
    obj.print();

    return 0;
}

答:i 是随机值,j 是 2。因为 i 的空间先分配,再分配 j。

8、main函数执行前还会执行什么代码?

考点:对构造函数调用周期的理解

#include <iostream>

using namespace std;

class Test
{
    public:
        Test()    //构造函数
        {
            cout << "constructor of Test" << endl;
        }
};

Test a;    //全局变量 ,存储在数据段。 数据段的空间先存在

int main()
{
    cout << "main() start" << endl;
    Test b;    //局部变量
    return 0;
}

编译运行:

可见,这份代码,会先执行全局对象的构造函数。

9、函数重载的正确声明

判断题:

(1) int calc(int,int);
    int calc(const int,const int);
    //会出现二义性!!

(2) int get();
    double get();
    //错误

(3) int *reset(int *);
    double *reset(double *);
    //正确

(4) extern "C" int compute(int *,int);
    extern "C" double compute(double *,double);
    //错误

10、什么是临时对象?临时对象在什么情况下会产生?

//演示临时对象的产生
#include <iostream>

using namespace std;

class base
{
    public:
        base(int d):date(d)
        {
            
        }

        void show()
        {
            cout << "date: " << date << endl;
        }

        int date;
};

//修改base的值
void change_base(base tmp)    //因为 tmp 是一个临时对象,相当于又产生了个临时对象的空间,只在函数中有效!!
{
    tmp.date = 10086;
}

//防止临时对象的产生: 引用
//修改base的值
void change_base1(base &tmp)
{
    tmp.date = 10086;
}

//当一个对象,作为参数传递时,就会产生临时对象!!
int main()
{
    base a(100);
    a.show();

    //修改base的值
    change_base(a);
    a.show();

    //修改base的值
    change_base1(a);
    a.show();

    return 0;
}

编译运行:

可以,发现对象 a 中的值并未被改变。

当一个对象,作为参数传递时,就会产生临时对象!!

如何防止临时对象的产生呢??

传递参数的时候,传递类的引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值