c++ primer plus第十章习题答案

第一题到第八题已经补全,但是第八题个人理解按照题上的说法做,即函数指针,没有什么意义。也有可能是我没有理解清楚题意吧。我想明白后会回来再做修改,也希望各位能提一些意见一起探讨!


第一题

count.h

//***************************************************************************************//
//*****************************************count.h***************************************//
#ifndef COUNT_H_
#define COUNT_H_

#include <string>

class BankCount
{
private:
	std::string m_name;
	double m_countNum;
	double m_deposit;
public:
	BankCount();
	BankCount(const std::string &co, double recvCountNum = 0, double recvDeposit = 0);
	~BankCount();
	void addr();
	void input(const double store);
	void output(const double expense);
	void display() const;	// promises not to change invoking object
};


#endif
//***************************************************************************************//

count.cpp

#include <iostream>
#include <iomanip>
#include "count.h"

BankCount::BankCount()		// default constructor
{
	std::cout << "Default constructor called.\n";
	m_name = "NULL";
	m_countNum = 0;
	m_deposit = 0;
}

BankCount::BankCount(const std::string &co, double countNum, double deposit)
{
	std::cout << "Constructor using " << co << " called.\n";
	m_name = co;
	m_countNum = countNum;
	if(deposit < 0)//--------------------------string object duplicate?????????????????
	{
		std::cout << "Initial deposit money can not be negative."
			<<" Deposit money is set to 0.\n\n";
		m_deposit = 0;
	}
	else
	{
		m_deposit = deposit;
	}
}

BankCount::~BankCount()
{
	std::cout << "Bye!\n";
}

void BankCount::addr(void)
{
	std::cout << (void *)&m_name << "\n";
}

void BankCount::input(const double store)
{
	if(store < 0)
	{
		std::cout << "Number of storing money can not be negative.\n\n";
	}
	else
	{
		m_deposit = m_deposit + store;
		std::cout << "$" << store << " is stored.\n\n";
	}
}

void BankCount::output(const double expense)
{
	if(expense <= 0)
	{
		std::cout << "Number of expensed money can not be negative.\n\n";
	}
	else
	{
		if(expense - m_deposit)
		{
			std::cout << "Number of expensing money exceeds deposit money.\n"
				<< "Deposit money is $" << m_deposit << ".\n\n";
		}
		else
		{
			m_deposit = m_deposit - expense;
			std::cout << "$" << expense << " is expensed.\n\n";
		}
	}
}

void BankCount::display() const
{
	using namespace std;
	std::cout << m_name << ": \n";
	std::cout << setprecision(20) << "Count number: " << m_countNum << ".\n";
	std::cout << "Deposit money: $" << m_deposit << ",\n\n";
}


main.cpp

#include <iostream>
#include <stdlib.h>
#include "count.h"

int main()
{
	double moneyinput,moneyoutput;
	int execute = 0;
	std::string a = "Mark Wall";
	BankCount member1(a, 1001001101001100, 30000);

	std::cout << (void *)&a << "\n";
	member1.addr();

	member1.display();
	
	while(execute != 4)
	{
		std::cout << "Choose the option:\n"
			<< "1. Enter the number of money you want to store: \n"
			<< "2. Enter the number of money you want to expense:; \n"
			<< "3. Display your count.\n"
			<< "4. Quit.\n";
		std::cin >> execute;
		switch(execute)
		{
			case 1:
				std::cout << "Enter the money: ";
				std::cin >> moneyinput;
				member1.input(moneyinput);
				break;
			case 2:
				std::cout << "Enter the money: ";
				std::cin >> moneyoutput;
				member1.output(moneyoutput);
				break;
			case 3:
				member1.display();
				break;
			case 4:
				break;
			default:
				std::cout << "Wrong choose!\n";
		}
	}

	return 0;
}


第二题

person.h

//*************************************************************************//
//**********************************person.h*******************************//
#ifndef PERSON_H_
#define PERSON_H_

#include <string>

class Person
{
private:
	static const int LIMIT = 25;
	std::string lname;		// Person's last name
	char fname[LIMIT];	// Person's first name
public:
	Person() {lname = ""; fname[0] = '\0';}	// #1
	Person(const std::string & ln, const char * fn = "Heyyou");	// #2
	~Person();
	// the following methods display lname and fname
	void Show() const;			// firstname lastname format
	void FormalShow() const;	// lastname, firstname format
	void Addr() const;
};



#endif
//*************************************************************************//

person.cpp

#include <iostream>
#include <cstring>
#include "person.h"

Person::Person(const std::string & ln, const char * fn)
{
	int str;
	lname = ln;
	str = strlen(fn);
	std::cout << "length of first name: " << str << std::endl;
	strncpy(fname, fn, str+1);
}

Person::~Person()
{
	std::cout << "Bye\n";
}

void Person::Show(void) const
{
	std::cout << fname << " " << lname << "\n";
}

void Person::FormalShow(void) const
{
	std::cout << lname << " " << fname << "\n";
}

void Person::Addr(void) const
{
	std::cout << "Address of char is " << (void *)fname << ". This address is the address of string\n";
	std::cout << "Address of string class is " << &lname << ". This address is not the address of string\n";
	//std::cout <<  << std::endl;  //how to output the address of string in the class string?
}

main.cpp

#include <iostream>
#include <string>
#include "person.h"

using namespace std;

int main()
{
	Person one;						// use default constructor
	Person two("Smythecraft");		// use #2 with one default argument
	Person three("Dimwiddy", "Sam");// use #2, no defaults
	cout << endl;

	cout << "Address of two's \"Smythecraft\" is " 
		<< (void *)"Smythecraft" 
		<< endl << endl;;
	
	one = two;
	one.Show();
	one.FormalShow();
	one.Addr();
	cout << endl;

	one = Person();

	two.Show();
	two.FormalShow();
	two.Addr();
	cout << endl;

	three.Show();
	three.FormalShow();
	three.Addr();
	cout << endl;
	
	return 0;
}


第三题

golf.h

//*****************************************************************//
//*******************************golf.h****************************//
// golf.h -- for pe9-1.cpp
#ifndef GOLF_H_
#define GOLF_H_


class Golf
{
private:
	static const int LEN = 40;
	char m_fullname[LEN];
	int m_handicap;
public:
	// non-interactive version:
	// function sets golf structure to provided name, handicap
	// using values passed as arguments to the function
	Golf() {m_fullname[0] = '\0'; m_handicap = 0;}
	Golf(const char * name, const int hc);
	~Golf();
	// interactive version:
	// fuction solicits name and handicap from user
	// and sets the members of g to the values entered
	// returns 1 if name is entered, 0 if name is empty string
	Golf setgolf();
	// function resets handicap to new value
	void handicap(int hc);

	// function displays contents of golf structure
	void showgolf() const;
};



#endif
//*****************************************************************//

golf.cpp

#include <iostream>
#include <cstring>
#include "golf.h"

extern int ret;

Golf::Golf(const char * name, const int hc)
{
	strcpy_s(m_fullname, name);
	m_handicap = hc;
}

Golf::~Golf()
{
	//
}

Golf Golf::setgolf(void)
{
	using namespace std;
	char fullname[40];
	int handicap;

	cout << "Enter fullname less than 40 words:" << endl;
	cin.getline(fullname,40);

	if(fullname[0] == '\0')
		ret = 0;
	else
	{
		cout << "Enter handicap:" << endl;
		cin >> handicap;
		cin.get();

		*this = Golf(fullname, handicap);
	}

	return *this;
}

void Golf::handicap(int hc)
{
	m_handicap = hc;
}

void Golf::showgolf(void) const
{
	using namespace std;
	cout << "fullname: " << m_fullname << endl;
	cout << "handicap: " << m_handicap << endl;
}

main.cpp

#include <iostream>
#include "golf.h"

int ret = 1;

int main()
{
	Golf ann[10];
	int count = 0;
	do{
		if(count%2 == 0)
		{
			ann[count] = ann[count].setgolf();
		}
		else
		{
			using namespace std;
			char temp[40];
			int num;
			cout << "Enter fullname less than 40 words:" << endl;
			cin.getline(temp,40);
			if(temp[0] == '\0')
			{
				break;
			}
			else
			{
				//
			}
			cout << "Enter handicap:" << endl;
			cin >> num;
			cin.get();
			ann[count] = Golf(temp, num);
		}
		count ++;
	}while((ret == 1)&&(count < 10));

	ann[0].showgolf();
	ann[0].handicap(6);
	ann[0].showgolf();

	return 0;
}


第四题

sales.h

//***********************************************//
//*******************sales.h*********************//
#ifndef SALES_H_
#define SALES_H

namespace SALES
{
	class Sales
	{
	private:
		static const int QUARTERS = 4;
		double sales[QUARTERS];
		double average;
		double max;
		double min;
		void findaver(int n);
		void findmax(int n);
		void findmin(int n);
	public:
	// copies the lesser of 4 or n items from the array ar
	// to the sales member of s and computes and stores the
	// average, maximum, and minimum values of the entered items;
	// remaining elements of sales, if any, set to 0
		Sales() {sales[0] = '\0'; average = 0; max = 0; min = 0;}
		Sales(const double ar[], int n);
		~Sales(){}
		// gathers sales for 4 quarters interactively, stores them
		// in the sales member of s and computes and stores the
		// average, maximum, and minimum values
		Sales setSales();
		// display all information in structure s
		void showSales() const;
	};
}


#endif SALES_H_
//***********************************************//

sales.cpp

#include <iostream>
#include <stdlib.h>
#include "sales.h"

namespace SALES
{
	Sales::Sales(const double ar[], int n)
	{
		using std::cout;
		if(n > 4 || n < 0)
		{
			cout << "error! n is out of range.\n";
			_exit(-1);			// force to quit the whole program
		}						// exit(0),exit(non-0),_exit(0),_exit(non-0) is different from each other.
		else					// _exit(): loss the data in the buffer, exit(): hold the data in the buffer
		{						// exit(0): quit normally, exit(non-0): quit abnormally
			for(int i = 0; i < n; i++)
				sales[i] = ar[i];

			findaver(n);
			findmax(n);
			findmin(n);
			
			for(int i = 0; i < 4; i++)
				sales[i] = 0;
		}
	}

	Sales Sales::setSales(void)
	{
		using std::cout;
		using std::cin;

		int n;
		double temp[4];
		cout << "Set the sales number no more than 4: ";
		cin >> n;
		if(n > 4 || n < 0)
		{
			cout << "error! n is out of range.\n";
			_exit(-1);
		}
		else
		{
			for(int i = 0; i < n; i++)
			{
				cout << "input the #" << i+1 << " sale: ";
				cin >> temp[i];
			}
			*this = Sales(temp, n);	
			return *this;
		}
	}

	void Sales::findaver(int n)
	{
		double total = 0;
		for(int i = 0; i < n; i++)
		{
			total = total + sales[i];
		}
		average = total / n;
	}

	void Sales::findmax(int n)
	{
		max = sales[0];	// initialize max and min, compare with each one
			
		for(int i = 0; i < n; i++)
		{	
			if(sales[i] > max)
				max = sales[i];
		}
	}

	void Sales::findmin(int n)
	{
		min = sales[0];
		for(int i = 0; i < n; i++)
		{
			if(sales[i] < min)
				min = sales[i];
		}
	}

	void Sales::showSales() const
	{
		using std::cout;
		using std::endl;
		cout << endl << endl;;
		cout << "average of sale is " << average << endl;
		cout << "max value of sale is " << max << endl;
		cout << "min value of sale is " << min << endl;
	}
}

main.cpp

#include "sales.h"
using namespace SALES;

int main()
{
	double a[] = {3,4,5,6};
	Sales obj1(a, 4), obj2;
	obj2 = obj2.setSales();
	obj1.showSales();
	obj2.showSales();
	return 0;
}

第五题

stack.h

//**********************************************************************//
//*********************************stack.h******************************//
#ifndef STACK_H_
#define STACK_H_

typedef struct
{
	char fullname[35];
	double payment;
}customer;


class Stack
{
private:
	static const int MAX = 10;	//constant specific to class
	customer m_items[MAX];		// holds stack items
	int m_top;					// index for top stack item
	double m_gloss;		// store total value
public:
	Stack();
	~Stack();
	bool isempty() const;
	bool isfull() const;
	// push() returns false if stack already is full, true otherwise
	bool push(const customer & obj);	// add item to stack
	// pop() returns false if stack already is empty, true otherwise
	bool pop(customer & obj);			// pop top into item
	void show() const;					// show payment

};

#endif
//**********************************************************************//

stack.cpp

#include <iostream>
#include <cstring>
#include "stack.h"

Stack::Stack()
{
	m_top = 0;
	m_gloss = 0;
}

Stack::~Stack()
{
	//
}

bool Stack::isempty(void) const
{
	return (m_top == 0);
}

bool Stack::isfull(void) const
{
	return (m_top == MAX);
}

bool Stack::push(const customer & obj)
{
	if(m_top < MAX)
	{
		m_items[m_top].payment = obj.payment;
		int str;			// statement can be put in wherever but before being used
		str = strlen(obj.fullname);
		strncpy_s(m_items[m_top].fullname, obj.fullname, str+1);
		m_top++;
		return true;
	}
	else
		return false;
}

bool Stack::pop(customer & obj)
{
	if(m_top > 0)
	{
		int str;
		m_top--;
		m_gloss = m_gloss + m_items[m_top].payment;// add the value of payment to gloss
		obj.payment = m_items[m_top].payment;
		str = strlen(m_items[m_top].fullname);
		strncpy_s(obj.fullname, m_items[m_top].fullname, str+1);
		return true;
	}
	else
		return false;
}


void Stack::show(void) const
{
	std::cout << "\n" << "Now " << m_top << " elements are in stack.\n"
		<< "The point \"top\" is pointing to " << m_top << ".\n"
		<< "The total number of payment is " << m_gloss << "\n";
}

main.cpp

#include <iostream>
#include "stack.h"

void showobj(customer obj, int n)
{
	std::cout << "#" << n+1 << ": " << obj.fullname << ": " << obj.payment << "\n";
}

int main()
{
	Stack obj_stack;
	customer recv[11] = {};				// 初始化
	customer object[11] = {				// 如果不初始化,每个元素里将有随机值,输出乱码
		{"Adobe Reader", 1.1},			// 初始化后如果某位或几位为缺省,则对应元素为0
		{"Microsoft Office", 2.2},
		{"Photo Shop", 3.3},
		{"Surface Pro", 4.4},
		{"Google Chrome", 5.5},
		{"Quartus II", 6.6},
		{"Daemon Tools", 7.7},
		{"VM Ware", 8.8},
		{"TuneUp", 9.9},
		{"Sketch Up", 10},
		{"Whatever", 11.11}
	};
	for(int i = 0; i < 11; i++)
		showobj(object[i], i);			// 输出将要压入栈的元素
	obj_stack.show();					// 输出此时栈的情况
	
	while(!obj_stack.isfull())
	{
		static int j = 0;
		while(!obj_stack.push(object[j]))	// 压栈,如果成功将不执行while语句
		{									// 应该不会出现失败的情况,
			std::cout << "Unknown push error!\n";// 之所以这样写是处于个人习惯
			_exit(1);
		}
		j++;
	}
	obj_stack.show();

	while(!obj_stack.isempty())				// 出栈,原理同上
	{
		static int k = 0;
		while(!obj_stack.pop(recv[k]))
		{
			std::cout << "Unknown pop error!\n";
			_exit(1);
		}
		k++;
	}
	obj_stack.show();						// 输出此时栈的情况
	std::cout << std::endl;

	for(int i = 0; i < 11; i++)
		showobj(recv[i], i);				// 输出接收器接收的数据

	return 0;
}


第六题

move.h

//****************************************************************************//
//**********************************move.h************************************//
#ifndef MOVE_H_
#define MOVE_H_

class Move
{
private:
	double x;
	double y;
public:
	Move(double a = 0, double b = 0);		// sets x, y to a, b
	~Move() {}
	void showmove() const;						// shows current x, y values
	Move add(const Move & m) const;
	// this function adds x of m to x of invoking object to get new x,
	// adds y of m to y of invoking object to get new y, creates a new
	// move object initialized to new x, y values and returns it
	void reset(double a = 0, double b = 0);		// resets x, y to a, b
};


#endif
//****************************************************************************//

move.cpp

#include <iostream>
#include "move.h"

Move::Move(double a, double b)
{
	x = a;
	y = b;
}

void Move::showmove(void) const
{
	std::cout << "current x = " << x << "\n"
		<< "current y = " << y << "\n\n";
}

Move Move::add(const Move & m) const
{
	double xt = x + m.x;
	double yt = y + m.y;
	return (Move(xt, yt));
}

void Move::reset(double a, double b)
{
	x = a;
	y = b;
}

main.cpp

#include <iostream>
#include "move.h"

int main()
{
	Move obj1;
	Move obj2(1.1, 2.2);
	Move obj3 = Move(3.3, 4.4);

	std::cout << "object1:\n";
	obj1.showmove();
	std::cout << "object2:\n";
	obj2.showmove();
	std::cout << "object3:\n";
	obj3.showmove();

	std::cout << "after 1st addition, object3:\n";
	obj3 = obj1.add(obj2);
	obj3.showmove();
	std::cout << "after 2nd addition, object3:\n";
	obj3 = obj3.add(obj2);				// 合法,等号右边创建临时对象,没有修改obj3,
	obj3.showmove();					// 把临时对象赋给obj3,这时obj3已经不是const
	std::cout << "after reset, object3:\n";
	obj3.reset(1, 1);
	obj3.showmove();

	return 0;
}


第七题

plorg.h

//**************************************************************************//
//*********************************plorg************************************//
#ifndef PLORG_H_
#define PLORG_H_

class Plorg
{
private:
	enum {MAX = 20};
	char m_name[MAX];
	int m_CI;
public:
	Plorg();
	Plorg(char * s);
	~Plorg() {}
	void changeCI(int temp);
	void show() const;
};


#endif
//**************************************************************************//

plorg.cpp

#include <iostream>
#include <cstring>
#include "plorg.h"

Plorg::Plorg()
{
	strcpy(m_name, "Plorga");
	m_CI = 50;
}

Plorg::Plorg(char * s)
{
	int str = strlen(s);
	//strncpy_s(m_name, 20, s, str+1);
	strncpy_s(m_name, s, str+1);// 与上一句等效,拷贝19和str中较小的字符数,在结尾处加'\0'
								// 实际测试中发现拷贝字符数多于19个时强制退出并报错
	m_CI = 50;
}

void Plorg::changeCI(int temp)
{
	m_CI = temp;
}

void Plorg::show(void) const
{
	std::cout << "plorg name: " << m_name << "\n"
		<< "plorg CI: " << m_CI << "\n";
}

main.cpp

#include <iostream>
#include <string>
#include "plorg.h"

int main()
{
	using namespace std;
	//char na[24]= "asdfasdfasdfasdfasdfas";
	string name;
	Plorg obj1;
	Plorg obj2("Betelgeusean");

	cout << "object1:\n";
	obj1.show();
	cout << "object2:\n";
	obj2.show();

	cout << "Enter the name of object1 less than 20 words: ";
	getline(cin, name);
	Plorg obj3((char *)name.c_str());	// name是string类的对象,字符串地址需要通过方法c_str得到
	//Plorg obj3(na);					// 直接对name取址得到的是对象地址
	obj3.show();

	obj2.changeCI(60);
	cout << "object2:\n";
	obj2.show();

	return 0;
}


第八题

list.h

//********************************************************************************//
//************************************list.h**************************************//
#ifndef LIST_H_
#define LIST_H_

typedef int Item;// 默认Item为int型,可以换为其他基本数据类型,不能为结构体
//typedef double Item;
//typedef float Item;
//typedef short Item;
//typedef char Item;

void show(Item &);

class List
{
private:
	void * m_pt;// 设置成空指针是为了能够指向任意类型的数据
	int m_pos;	// 标记表示当前存储数据的位置,实际上是数组中下一个为空的位置,类似于栈
	int m_MAX;	// 存储列表可容纳的数据个数
public:
	List();
	List(const int n);
	~List();
	bool isempty() const;
	bool isfull() const;
	bool add(const Item &);
	void visit(void (*pt)(Item &)) const;
};


#endif
//********************************************************************************//

list.cpp

#include <iostream>
#include "list.h"

List::List()
{
	//m_pt = new int [1];		// 只有一个int型0元素的列表
	//*(int *)m_pt = 0;
	//m_MAX = 1;
	//m_pos = 1;
	m_pt = NULL;				// 指针指向空,空列表
	m_pos = 0;
	m_MAX = 0;
}

List::List(const int n)
{
	m_pt = new Item [n];
	m_pos = 0;
	m_MAX = n;
	(Item *)m_pt;
}

List::~List()
{
	delete [] m_pt;				// 在析构函数里要把m_pt指针指向的空间释放
}

bool List::isempty(void) const
{
	return (m_pos == 0);
}

bool List::isfull(void) const
{
	return (m_pos == m_MAX);
}

bool List::add(const Item & item)
{
	if(isfull())
		return false;
	else
	{
		*((Item *)m_pt+(m_pos++)) = item;// 强制转换m_pt指向的数据类型,后面加偏移地址
		return true;
	}
}

void List::visit(void (*pt)(Item &)) const	// 该函数隐式访问类内数据,接收函数指针为参数
{
	int flag = 0;	// 标记没有找到数据
	Item item;		// item是函数指针指向的函数的参数,要在visit内声明
	std::cout << "Enter the element you want to visit: ";
	std::cin >> item;
	for(int i = 0; i < m_pos; i++)
	{
		if(item == *((Item *)m_pt+i))// 左值,要找的参数;右值,列表中的数据
		{
			std::cout << "Find " << item << " in position " << i+1 << std::endl;
			(*pt)(item);
			flag++;
		}
	}
	if(flag == 0)
		std::cout << "No such item has been found!\n";
}

void show(Item & item)	// 这个函数有什么意义我还没有想明白,莫非只是为了展示一下
{						// 函数指针技术?弄清楚后会回来补充
	std::cout << item << "\n";
}

main.cpp

#include <iostream>
#include "list.h"

int main()
{
	using std::cout;
	using std::cin;
	List Tlist(5);// 可以交互式输入列表容量,为了简单直接给5
	Item temp;
	int option = 0;

	while(option != 5)
	{
		cout << "choose the option:\n";
		cout << "1. check if the list is empty.\n"
			<< "2. check if the list is full.\n"
			<< "3. add element to the list.\n"
			<< "4. visit a element.\n"
			<< "5. quit.\n";
		cin >> option;
		switch(option)
		{
		case 1:
			if(Tlist.isempty())		// 检查是否为空
				cout << "The list is empty.\n";
			else
				cout << "The list is not empty.\n";
			break;
		case 2:
			if(Tlist.isfull())		// 检查是否为满
				cout << "The list is full.\n";
			else
				cout << "The list is not full.\n";
			break;
		case 3:
			if(!Tlist.isfull())		// 不为空时可以添加数据
			{
				cout << "Enter the item you want to add in: ";
				cin >> temp;
				if(Tlist.add(temp))
					cout << "Add operation Succeed!\n";
				else
					cout << "Add operation fail!\n";
			}
			else
				cout << "The list is already full!\n";
			break;
		case 4:						// 查找元素
			if(!Tlist.isempty())
				Tlist.visit(show);
			else
				cout << "The list is empty, no element exists!\n";
			break;
		case 5:
			break;
		default:
			cout << "Entered the wrong number, please enter again: ";
		}
		cout << std::endl;
	}

	cout << "Bye!\n";

	return 0;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《C Primer Plus第六版》是一本面向初学者的C语言教材,由Stephen Prata撰写。这本书深入浅出地介绍了C语言的基本概念、语法和应用,给读者提供了扎实的编程基础。 该书共分为27章,每章都有清晰的目标、易于理解的示例和练习题。从第一章的入门介绍开始,到最后一章的高级主题讨论,书中的内容依次递进,系统完整地覆盖了C语言的方方面面。本书有助于读者逐步掌握C语言的基础知识,从简单的输出语句到复杂的函数调用和指针使用。 《C Primer Plus第六版》的特点是其清晰的讲解风格和丰富的实例。作者通过通俗易懂的语言和生动形象的例子,帮助读者理解和掌握C语言的各种概念和语法。此外,书中还提供了许多练习题和编程项目,供读者巩固所学知识和提高编程能力。 作为一本经典的C语言教材,《C Primer Plus第六版》被广泛用于学校和个人学习。它不仅适用于初学者,也对有一定编程基础的读者有所帮助。读者通过学习本书,可以建立起对C语言编程的扎实基础,为深入学习其他编程语言打下坚实的基础。 综上所述,《C Primer Plus第六版》是一本权威、经典的C语言教材,通过清晰的讲解和丰富多样的示例帮助读者深入理解C语言的基本概念和应用。无论是初学者还是有一定编程基础的读者,都可以从中获益,打下良好的编程基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值