C++是一种语言,仅仅是它的语法、特性、标准类库就已经是一门非常高深的课程,所以在开始学习的时候,必项先要打好基础。
C语言有一个优点,即它的速度可以很快。写出来的程序可以很精练、简单、小巧,如果将C和C++相比较,C++就经常会为了解决某个问题绕一个大圈,所以代码量相对较大,并且里边有一些不是必项的代码。但C++有个绝对的优势,就是针对不同的对象去做实例化,这就是所谓的OO(Object Oriented:面向对象)思想。
在面对对象的思想中,任何事物都可以被看做一个对象。一个再复杂的模型结构都是由千千万万个对象组成的。这是根本思想。
例如:地球可以看做一个相当复杂的对象地球.上的每种动物、每种植物、空气、水、土壤等都是对象。
它们彼此之间互相联系、组合最终形成了地球。而对于每个对象,抽象起来最终可以分为两个要素:属性和行为。
在面对对象编程中,程序员不再面对一个个函数和变量,而是要放眼大局,面对一个个对象来看问题。
每个对象都是一个完整的独立的个体,它是由相关的属性和行为组合,与外界分隔。
例如,一家跨国公司,它在全球有很多分公司,每个公司都有自己的员互和一套自己的运作体系。对于总公司而言,分公司好比“黑箱”总公司不需干预分公司如何调配人员工作等,只需下达命令和指标。
面向对象是当前软件开发方法的主流,其概念和应用早已超越了程序设计和软件开发本身而扩展到更加宽广的范围。
举个例子,例如我们的图形用户界面(GUI)编程,面向对象在这方面的能力是相当出众,以至于人们在那些并不直接支持面向对象的语言(例如C)中也创建了一些模拟OO的软件结构,以便进行GUI编程。典型例子:GNOME/GTK+工具。
面向对象的4个特点:
1.封装
封装意味着把对象的属性和方法结合成一个独立的系统单位,并尽可能隐藏对象的内部细节。封装是面向对象思想描述的基础,从此程序员面对的就不再是许多复杂的函数和过程实现,而是少数具有行为能力的个体实例。
2.抽象
抽象的过程是对具体问题进行概括的过程, 是对一类公共问题进行统一描述的过程。为了使某些必要的信息得以顺利的交流,设计者必项制定一个抽象,就如同切个协议,个得到所有参与活动的有效个体支持的协议。
3.继承
子类对象拥有与其基类相同的全部属性和方法,称为继承。
4.多态
多态是指在基类中定义的属性和行为被子类继承后,可以具有不同的数据类型或者表现行为等特性。
下节课,我们将通过实例对t比C和C++在编程上的差异来进行学习。
问题:对一个整型数组求和。
要求:定义一个存储着n个元素的数组,要求用C语言完成这个任务。
#include
int main(){
int data[]={
0,1,2,3,4,5,6,7,8,9};
int size = sizeof(data) / sizeof(data[0]);
printf("data size是: %d\n", sizeof(data));//size is 40
printf("结果是: %d\n", addArray( data, size ));
return 0;
}
int addArray( int array[], int n ){
int sum = 0;
int i;
printf("array size是: %d\n", sizeof(array));//size is 4
for(i=0;i<n;i++)
sum += array [i] ;
return sum; //45
}
思考:
数组名与指针的关系:在《C专家编程》中作者采用大篇幅对C的数组和指针作了对比来跟我们说数组和指针他们的关系很复杂。数组名就是传递指针,因为传递一个首地址不会浪费空间。
//上面参数data数组名就相当于是数组的首地址,使用指针得到相同的结果
int addArray( int *array, int n ){
int sum = 0;
int i;
for(i=0;i<n;i++)
sum += *array++ ;//地址偏移
return sum; //45
}
以上两个程序从本质上来说是相同的,我们得出结论:将函数的参数声明为数组和声明为指针是一样的。现在我们来考虑一个新的问题:将该程序用C++来实现试试。
#include
using namespace std;
//上面参数data数组名就相当于是数组的首地址,使用指针得到相同的结果
int addArray( int array[], int n ){
int sum = 0;int i;
for(i=0;i<n;i++)
sum += array[i] ;//地址偏移
return sum; //45
}
int main(){
int data[]={
0,1,2,3,4,5,6,7,8,9};
int size = sizeof(data) / sizeof(data[0]);
cout << "结果是: " << addArray( data, size ) << endl;
return 0;
}
程序分析
这个小程序展示了C++对象的第一次使用。对象在哪里只就是这个cout。cout是一个输出流对象,它是”’console out(控制台输出)“的缩写。 是属于basic_ ostream 类的对象。ostream类在iostream头文件中定义。注意
什么是输出流?其实也就是一个概念,在C++中引入了很多类似的概念:例如数据可以从键盘流入程序,又可以从程序流向屏幕、打印机等~
using namesapce std;
这条指令带给我们一个全新的概念:名字空间。就是C++标准库所使用的所有标识符(即类、函数、对象等的名称)都是在同一个特殊的名字空间(std)中来定义的。
如果我们没有使用这条指令,我们将需要使用std::cout这样的语法来调用输出流对象。
不知道大家有没有注意到“<<” 这个符号很眼熟。这个操作符不是C语言里边位运算的左移操作符吗?难道在C++里边改规则了事实上不是这样的,它只不过体现了C++的另一个特点:支持重载。重载事实上就是允许我们按照不同的方式使用同一个操作符。我们后边会详细讲解。
课后思考
要求:编写一个程序,要求用户输入一串整数和任意数目的空格,这些整数必项位于同一行中,但允许出现在该行中的任何位置。当用户按下键盘上的“Enter” 键时,数据输入结束程序自动对所有的整数进行求和并打印出结果。
#include
#include
void main(){
int i;
int sum = 0;
char ch;
printf("请输入一串整数和任意数目的空格: ");
while( scanf("%d", &i) == 1 ){
sum += i;
while( (ch=getchar()) == ' ' ) ;
if( ch == '\n' ) {
break;
}
ungetc( ch, stdin );
}
printf("结果是: %d", sum);
}
c++版除了输入输出整体没有变化
#include
using namespace std;
int main(){
int i,sum=0;
char c;
cout<< "input num:";
while(cin >> i){
sum += i;
while((c = getchar()) == ' ') ;
if(c == '\n'){
break;
}
ungetc(c,stdin);
}
cout<<"sum is"<<sum << endl;
return 0;
}
例子一:cin.ignore() & cin.getline()
#include
using namespace std;
int main(){
char buf[20];
cin.ignore(7); //忽略了前7个字符
cin.getline( buf, 10 ); //取10个字符进buf数组,结尾是'0'
//输入了12345678901234562890
cout << buf << endl; //890123456 输出了9个,因为结尾有0
return 0;
}
例子二:cin.get() & cin.peek()
int main(){
char p;
cout << "请输入一段文本: \n";
while( cin.peek() != '\n' ){
//输入进流对象直到换行
p = cin.get(); //得到字符放入p中
cout << p; //输入:123,输出:123
}
cout << endl;
return 0;
}
例子三:cin.gcount() & cin.read()
int main(){
const int SIZE = 50;
char buf[SIZE];
cout << "请输入一段文本: ";
cin.read( buf, 20 ); //读取20个字符
cout << "字符串收集到的字符数为: "
<< cin.gcount() << endl; //收集到字符个数
cout << "输入的文本信息是: ";
cout.write( buf, 20 ); //输出20个字符
cout << endl;
return 0;
}
int main(){
double result = sqrt(3.0);
cout << "对 3 开方保留小数点后0 ~ 9 位,结果如下: \n" << endl;
for( int i=0; i <= 9; i++ ){
cout.precision(i);
cout << result << endl;
}
cout << "当前的输出精度为: " << cout.precision() << endl;
return 0;
}
实例二:cout.width()
int main(){
int width = 4;
char str[20];
cout << "请输入一段文本: \n";
cin.width(5);
while( cin >> str ) {
cout.width(width++);
cout << str << endl;
cin.width(5);
}
return 0;
}
编程任务:编写一个文件复制程序,功能实现将一个文件复制到另一个文件。
例如:fileCopy sourceFile destFile
#include
#include
int main( int argc, char* argv[] ){
//声明的两个文件指针,它们的类型都是 FILE*,分别作为两个 I/O 流对象使用
FILE *in, *out;//
//getc() 的返回值是 int 类型哦,所以我们声明时应该是 int ch。而不是char ch
int ch; //
if( argc != 3 ){
//确保程序参数个数的正确性
fprintf( stderr, "输入形式: copyFile 源文件名 目标文件名 \n" );
exit( EXIT_FAILURE );
}
//以二进制的形式按可读/可写方式打开两个文件并返回两个文件指针给 in 和 out
//如果未成功打开,我们就向标准错误流 stderr 发送一条消息
if( ( in = fopen( argv[1], "rb") ) == NULL ){
fprintf( stderr, "打不开文件: %s \n", argv[1] );
exit( EXIT_FAILURE );
}
if( ( out = fopen( argv[2], "wb") ) == NULL ){
fprintf( stderr, "打不开文件: %s \n", argv[2] );
fclose( in ); // 记得擦屁股
exit( EXIT_FAILURE );
}
//getc函数一次从输入流(stdin) 读取一个字符
//getc() 遇到文件结束标志的时候返回eof
//EOF 是一个宏,在stdio.h中定义,其值为一个负整数,通常是 -1
while( (ch = getc(in)) != EOF ){
// EOF == end of file
//putc() 函数把这个字符写入到输出流(stdout)
if( putc( ch, out ) == EOF ){
break;
}
}
//EOF 事实上有两个含义,一个是读取结束,一个是读取错误,所以这里加了条件
if( ferror( in ) ) {
printf("读取文件 %s 失败! \n", argv[1] );
}
if( ferror( out )) {
printf("写入文件 %s 失败! \n", argv[2] );
}
printf("成功复制1个文件!\n");
fclose( in );
fclose( out );
return 0;
}
#include
#include
using namespace std;
int main(){
ifstream in;
in.open( "test.txt" ); // ifstream in( "test.txt" );
if( !in ) {
cerr << "打开文件失败" << endl;
return 0;
}
char x;
while( in >> x ){
//文件输入流读取文件内容
cout << x;
}
cout << endl;
in.close();
return 0;
}
上边的例题我们用到的是文件的读取类 ifstream。
接着我们结合例题来说说文件的写入要用到的类 ofstream
int main() {
ofstream out;
out.open( "test.txt" ); // ofstream out( "test.txt" );
if( !out ) {
cerr << "打开文件失败!" << endl;
return 0;
}
for( int i=0; i < 10; i++ ) {
out << i; //写入内容到文件输出流
}
out << endl;
out.close();
return 0;
}
ofstream out( "test.txt", ios::app ); //换行追加模式打开
int main(){
fstream fp("test.txt", ios::in | ios::out );
if( !fp ) {
cerr << "打开文件失败!" << endl;
return 0;
}
fp << "IloveFishc.com!";
static char str[100];
fp.seekg(ios::beg); // 使得文件指针指向文件头 ios::end 则是文件尾。
fp >> str;
cout << str << endl;
fp.close();
return 0;
}
c++版完整复制文件
int main(int count , char* arg[]){
if(count != 3){
cerr << "参数不正确!输入形式: copyFile 源文件名 目标文件名 \n" << endl;
return 0;
}
fstream is(arg[1], ios::in);
fstream os(arg[2], ios::out);
if( !is ) {
cerr << "打开文件失败!" << arg[1] << endl;
return 0;
}
if( !os ){
cerr << "打开文件失败!" << arg[2] << endl;
is.close();
return 0;
}
char ch;
while(is >> ch){
os << ch;
};
is.close();
os.close();
return 0;
题目:这个程序将向用户提出一个“Y/N”问题,然后把用户输入的值赋值给answer变量。
要求:针对用户输入‘Y’或‘y’和‘N’或‘n’进行过滤;发掘程序可能存在的任何问题,想想为什么?
如果是在exe运行的话,必须加上后三行,否则程序会一闪而过
#include
int main(){
char answer;
std::cout << "可以格式化您的硬盘吗?[Y/N]";
std::cin >> answer;
std::cout << "\n";
switch( answer ) {
case 'Y':
case 'y':
std::cout << "我想还是别了, 数据丢了妈妈会骂的~" << "\n";
break;
case 'N':
case 'n':
std::cout << "您的选择是正确的, 硬盘不能随便给人格式化!" << "\n";
break;
default:
std::cout << "请输入[Y/N]回答问题。" << "\n";
break;
}
std::cout << "输入任意键结束程序!" << "\n";
std::cin.get();
std::cin.ignore(100, '\n');//忽略前100个字符,直到遇到换行
return 0;
}
题目:编写一个“温度单位转换程序”,提示用户以【xx.x C】或【xx.x F】的格式输入。
要求:如果用户输入的是34.2 C 程序将自动转换为 90.32 F 并输出!
#include
int main(){
const unsigned short ADD_SUBTRACT = 32;
const double RATIO = 9.0 / 5.0;
float tempIn, tempOut;
char typeIn, typeOut;
std::cout << "请以【xx.x C】或【xx.x F】的形式输入温度: ";
std::cin >> tempIn >> typeIn;
std::cin.ignore(100, '\n');
std::cout << "\n";
switch( typeIn ){
case 'C':
case 'c':
tempOut = (tempIn * RATIO) + ADD_SUBTRACT;
typeOut = 'F';
typeIn = 'C';
break;
case 'F':
case 'f':
tempOut = (tempIn - ADD_SUBTRACT) / RATIO;
typeOut = 'C';
typeIn = 'F';
break;
default:
typeOut = 'E';
break;
}
if( typeOut != 'E' ){
std::cout << tempIn << typeIn << " = " << tempOut << typeOut << "\n\n";
} else{
std::cout << "请按照给出格式输入!" << "\n\n";
}
std::cout << "请输入任意字符结束!" << "\n";
std::cin.get();
return 0;
}
while( !(std::cin >> tempIn) ) {
std::cin.clear();
std::cin.ignore(100, '\n');
std::cout << "请以【xx.x】的形式输入温度: ";
}
do{
std::cout << "请以【xx.x C】或【xx.x F】的形式输入温度: ";
std::cin >> typeIn;
}while( (typeIn != 'C') && (typeIn != 'c') &&
(typeIn != 'F') && (typeIn != 'f') );
cin 对象有几个专门用来报告其工作情况的成员函数,它们将返回一个真/假值来表明cin 的状态。
实质就是用同样的名字再定义一个有着不同参数但有着同样用途的函数。
#include
void convertTemperature(double tempIn, char typeIn);
void convertTemperature(int tempIn, char typeIn);
int main()
{
double tempIn;
int tempInInt;
char typeIn;
std::cout << "请以【xx.x C】或【xx.x F】的形式输入温度: ";
std::cin >> tempIn >> typeIn;
std::cin.ignore(100, '\n');
std::cout << "\n";
convertTemperature(tempIn, typeIn); //浮点型输入输出
std::cout << "请以【xx C】或【xx F】的形式输入温度: ";
std::cin >> tempInInt >> typeIn;
std::cin.ignore(100, '\n');
std::cout << "\n";
convertTemperature(tempInInt, typeIn);//整型输入输出
return 0;
}
void convertTemperature(double tempIn, char typeIn)
{
const unsigned short ADD_SUBTRACT = 32;
const double RATIO = 9.0 / 5.0;
double tempOut;
char typeOut;
switch (typeIn)
{
case 'C':
case 'c':
tempOut = (tempIn * RATIO) + ADD_SUBTRACT;
typeOut = 'F';
typeIn = 'C';
break;
case 'F':
case 'f':
tempOut = (tempIn - ADD_SUBTRACT) / RATIO;
typeOut = 'C';
typeIn = 'F';
break;
default:
typeOut = 'E';
break;
}
if (typeOut != 'E')
{
std::cout << tempIn << typeIn << " = " << tempOut << typeOut << "\n\n";
}
else
{
std::cout << "请按照给出格式输入!"
<< "\n\n";
}
std::cout << "请输入任意字符结束!"
<< "\n";
std::cin.get();
}
void convertTemperature(int tempIn, char typeIn)
{
const unsigned short ADD_SUBTRACT = 32;
const double RATIO = 9.0 / 5.0;
int tempOut;
char typeOut;
switch (typeIn)
{
case 'C':
case 'c':
tempOut = (tempIn * RATIO) + ADD_SUBTRACT;
typeOut = 'F';
typeIn = 'C';
break;
case 'F':
case 'f':
tempOut = (tempIn - ADD_SUBTRACT) / RATIO;
typeOut = 'C';
typeIn = 'F';
break;
default:
typeOut = 'E';
break;
}
if (typeOut != 'E')
{
std::cout << tempIn << typeIn << " = " << tempOut << typeOut << "\n\n";
}
else
{
std::cout << "请按照给出格式输入!"
<< "\n\n";
}
std::cout << "请输入任意字符结束!"
<< "\n";
std::cin.get();
}
有以下几点需要大家注意的:
#include
#include
int main()
{
std::string str;
std::cout << "请随便输入一个字符串: ";
std::getline(std::cin, str);//getline不会忽略空格
std::cout << str << "\n";
return 0;
}
int a = 456;
char b = ‘C’;
int *aPointer = &a;
char *bPointer = &b;
这会让程序保留4个内存块,两个为变量保留,两个为指针保留。变量a 和变量b 里边存放的是变量的值; 两个指针变量存放着指针的值,这些值是其他变量的地址。如下图
一定要牢记的事实:指针所保存的是内存中的一个地址。它并不保存指向的数据的值本身。因此,务必确保指针对应一个已经存在的变量或者一块已经分配了的内存。
星号有两种用途,时常困惑了初学者:
第一种是用于创建指针:int *myPointer = &myInt;
第二种是对指针进行解引用: *myPointer = 3998;
C++ 允许多个指针有同样的值,随便修改一个其他两个都会变化
int *p1 = &myInt;
int *p2 = &myInt;
C++ 支持无类型(void)指针,就是没有被声明为某种特定类型的指针,例如:void *vPointer;
注意:对一个无类型指针进行解引用前,必须先把它转换为一种适当的数据类型
计算机把数组是以一组连续的内存块保存的,例如:int myArray[3] = {1, 2, 3};在内存中是类似于这种形式存储:
#include
int main()
{
const unsigned short ITEMS = 5;
int intArray[ITEMS] = {
1, 2, 3, 4, 5};
char charArray[ITEMS] = {
'F', 'i', 's', 'h', 'C'};
int *intPtr = intArray;
char *charPtr = charArray;
std::cout << "整型数组输出: " << '\n';
for( int i=0; i < ITEMS; i++ )
{
std::cout << *intPtr << " at " << intPtr << '\n';
intPtr++;
}
std::cout << "字符型数组输出: " << '\n';
for( int i=0; i < ITEMS; i++ )
{
std::cout << *charPtr << " at " << charPtr << '\n';
charPtr++;
}
return 0;
}
#include
void print( int *pBegin, int *pEnd )
{
while( pBegin != pEnd )
{
std::cout << *pBegin;
++pBegin;
}
}
void print( char *pBegin, char *pEnd )
{
while( pBegin != pEnd )
{
std::cout << *pBegin;
++pBegin;
}
}
int main()
{
int num[5] = {
0, 1, 2, 3, 4 };
char name[5] = {
'F', 'i', 's', 'h', 'C' };
print( num, num+5 );
std::cout << '\n';
print( name, name+5 );
std::cout << '\n';
return 0;
}
#include
template <typename elemType>
void print( elemType *pBegin, elemType *pEnd )
{
while( pBegin != pEnd )
{
std::cout << *pBegin;
++pBegin;
}
}
int main()
{
int num[5] = {
0, 1, 2, 3, 4 };
char name[5] = {
'F', 'i', 's', 'h', 'C' };
print( num, num+5 );
std::cout << '\n';
print( name, name+5 );
std::cout << '\n';
return 0;
}
小总结
结构(Structure)是一种由程序员定义的、由其他变量类型组合而成的数据类型。
当需要处理一些具有多种属性的数据时,结构往往是很好的选择。
定义一个结构的基本语法是:
struct Student
{
std::string name;
std::string uid;
char sex; // F==Female, M==Male
}
Student stu; // 创建一个Student结构类型的stu
stu.name = “小明”; //用”.”对结构成员进行赋值
stu.uid = “007”;
stu.sex = ‘M’;
Student stu = {
“小明”, “007”, ‘F’ }
Student *pstu = &stu;
//可以通过对指针进行解引用来访问相应的变量值
(*pstu).name = “小明2”;
(*pstu).id = “008”;
//第二种方法 和上面是一样的
pstu -> name = “小明3”;
pstu -> id = “009”;
pstu -> sex = F;
std::cout << pstu -> name;
std::cout << pstu -> id;
std::cout << pstu -> sex;
#include
#include
struct student
{
std::string name;
std::string uid;
char sex;
};
bool ReadStudent();
void RecordStudent();
bool WriteStudent(student *stu);
int main()
{
int i;
while (1)
{
std::cout << "请选择需要进行的操作: \n";
std::cout << "1. 打印数据到屏幕\n";
std::cout << "2. 录入数据\n";
std::cout << "3. 退出程序\n";
std::cin >> i;
switch (i)
{
case 1:
ReadStudent();
break;
case 2:
RecordStudent();
break;
case 3:
return 0;
}
}
return 0;
}
bool ReadStudent()
{
std::string info;
std::ifstream in("test.txt");
while (std::getline(in, info))
{
std::cout << info << "\n";
}
return true;
}
void RecordStudent()
{
std::string name;
std::string uid;
char sex;
std::cout << "输入姓名:" << std::endl;
std::cin >> name;
std::cout << "输入uid:" << std::endl;
std::cin >> uid;
std::cout << "输入sex:" << std::endl;
std::cin >> sex;
student f = {
name, uid, sex};
WriteStudent(&f);
}
bool WriteStudent(student *pstu)
{
std::ofstream out("test.txt", std::ios::app);
out << "\n"
<< pstu->name << " " << pstu->uid << " " << pstu->sex;
return true;
}
#include
void changeAge( int age, int newAge )
{
age = newAge;
std::cout << "In this , my age is " << age << "\n";
}
// 如果想要实现计划功能,需要怎么改?
main()
{
int age = 24;
std::cout << "My age is " << age << "\n";
changeAge( age, age+1 );
std::cout << "Now my age is " << age << "\n";
}
void changeAge( int *age, int newAge )
{
*age = newAge;
std::cout << "In this , my age is " << *age << "\n";
}
main()
{
int age = 24;
std::cout << "My age is " << age << "\n";
changeAge( &age, age+1 );
std::cout << "Now my age is " << age << "\n";
}
注意:如果传过去的是地址,在函数中必须要通过“*”对指针进行解引用,除非你有其他用途。
void swap( int *x, int *y )
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
main()
{
int x, y;
std::cout << "请输入两个不同的值:";
std::cin >> x >> y;
swap( &x, &y );
std::cout << "调换后输出:" << x << ' ' << y << "\n\n";
}
另外的一种不需要中介的互换方案,异或方式(加解密)
void swap( int *x, int *y )
{
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
main()
{
int x, y;
std::cout << "请输入两个不同的值:";
std::cin >> x >> y;
swap( &x, &y );
std::cout << "调换后输出:" << x << ' ' << y << "\n\n";
}
void swap( int &x, int &y )
{
int temp;
temp = x;
x = y;
y = temp;
}
main()
{
int x, y;
std::cout << "请输入两个不同的值:";
std::cin >> x >> y;
swap( x, y );
std::cout << "调换后输出:" << x << ' ' << y << "\n\n";
}
联合与结构有很多相似之处,联合也可以容纳多种不同类型的值,但是它每次只能存储这些值中的某一个。
应用情况:设有若干个人员的数据,其中有学生和教师,学生的数据中包括:姓名、号码、性别、职业、班级。教师的数据包括∶姓名、号码、性别、职业、职务。可以看出﹐学生和教师所包含的数据是不同的,现要求把它们放在同一表格中。
#include
struct{
int num;
char name[10];
char sex;
char job;
union{
int clas;
char position[10];
}category;
}person[2];
int main(){
int i;
for(i=0;i<2;i++){
printf("please enter the data of person:\n");
scanf("%d %s %c %c",&person[i].num,&person[i].name,&person[i].sex,&person[i].job);
if(person[i].job == 's')
scanf("%d", &person[i].category.clas);
else if(person[i].job == 't')
scanf("%s", person[i].category.position);
else
printf("Input error!");
}
printf("\n");
printf("No. name sex job class/position\n");
for(i=0;i<2;i++){
if (person[i].job == 's')
printf("%-6d%-10s%-4c%-4c%-10d\n",person[i].num, person[i].name,
person[i].sex, person[i].job, person[i].category.clas);
else
printf("%-6d%-10s%-4c%-4c%-10s\n",person[i].num, person[i].name,
person[i].sex, person[i].job, person[i].category.position);
}
return 0;
}
在实际问题中,有些变量的取值被限定在一个有限的范围内。
例 一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等。
如果把这些量说明为整型,字符型或其它类型显然是不妥当的。
设有变量a,b,c被说明为上述的weekday ,声明可以采用下述任一种方式:
enum weekday {
sun,mon,tue,wed,thu,fri,sat };
enum Weekday a, b, c;
或者为∶
enum weekday {
sun,mon,tue,wed,thu,fri,sat }a, b, c;
或者为∶
enum {
sun,mon,tue,wed,thu,fri,sat }a,b, c;
注意:
在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。
应该说明的是,枚举类型是一种基本数据类型﹐不是一种构造类型,因为它不能再分解为任何基本类型。
在枚举值表中应罗列出所有可用值。这些值也称为枚举元素。
编译中,对枚举元素按常量处理,故称枚举常量,它们不是变量,不能对它们赋值。
枚举元素作为常量,它你是有值的,编译按定义时的顺序使它们的值为0,1,…
枚举值可以用来作判断比较。
一个整数不能直接赋给一个枚举变量。
void main(){
enum weekday{
sun,mon,tue,wed,thu,fri,sat}a, b, c;
a = mon;//a = 1;有些编译器不行
b = thu;
c = sat;
printf("%d,%d,%d",a,b,c);//1,4,6
}
typedef保留字,声明新的类型名来代替已有的类型名,为一个类型定义创建一个别名。
声明 INTEGER为整型 typedef int INTEGER
声明结构类型 typedef struct{int month ;int day ;int year;}DATE;
typedef struct{
int month ;int day ;int year;}DATE;
void main(){
DATE d;
d.month = 12;
d.day =4;
d.year = 2030;
printf("%d,%d,%d",d.year,d.month ,d.day);//2030,12,4
}
声明NUM为整型数组类型 typedef int NUM [ 100] ;
声明STRING为字符指针类型 typedef char* STRING;
声明 POINTER为指向函数的指针类型,该函数返回整型值。
typedef int(*POINTER)();
typedef int NUM[100];
void main(){
NUM a = {
0};
printf("%d ",sizeof(a));//400
}
typedef char* P;
void main(){
P p1;
p1="I love China";
printf("%s",p1);
}
typedef void (*F)();
void fun(){
printf("I love China");
}
void main(){
F f ; // void (*f)();
f = fun; //相当于 f = &fun;
f();
}
class Car
{
public:
std::string color;
std::string engine;
unsigned int gas_tank;
unsigned int wheel;
void setColor(std::string col);
void setEngine(std::string eng);
void setWheel(unsigned int whe);
void fillTank(int liter); // 方法的声明:方法是”加油”,参数是”公升”
int running(void);
void warning(void);
};
void Car::setColor(std::string col)
{
color = col;
}
void Car::setEngine(std::string eng)
{
engine = eng;
}
void Car::setWheel(unsigned int whe)
{
wheel = whe;
}
void Car::fillTank(int liter)
{
gas_tank += liter;
}
int Car::running(void)
{
std::cout << "我正在以120的时速往前移动。。。越过那高山越过那河。。。\n";
gas_tank--;
std::cout << "当前还剩 " << 100*gas_tank/FULL_GAS << "%" << "油量!\n";
return gas_tank;
}
void Car::warning(void)
{
std::cout << "WARNING!!" << "还剩 " << 100*gas_tank/FULL_GAS << "%" << "油量!";
}
class Car
{
。。。。。。
} car1, car2;
这种做法在C++里是允许的。但作为一种良好的编程习惯,应该避免这种做法
Car car1, car2;
car1.setColor(“WHITE”);
。。。。。。
car2 = car1;
把一个对象赋值给另一个同类的对象将会自动使同名的属性有同样的值。
构造器和通常方法的主要区别:
创建构造器,需要先把它的声明添加到类里:
class Car {
Car( void );
};
Car::Car(void) // 不用写 void Car::Car(void)
{
color = “WHITE”;
engine = “V8”;
wheel = 4;
gas_tank = FULL_GAS;
}
class Car
{
Car(void);
~Car();
}
#include
#include
class Car
{
public:
std::ofstream output;
std::string color;
std::string engine;
unsigned int gas_tank;
Car();
~Car();
};
Car::Car(){
output.open("test.txt",std::ios::app);
}
Car::~Car(){
output.close();
std::cout << "调用析构器释放内存" << std::endl;
}
int main()
{
Car mycar;
std::cout << "输入车辆信息:" << std::endl;
std::cin >> mycar.color >> mycar.engine >> mycar.gas_tank ;
mycar.output << "\n" << mycar.color << " " << mycar.engine << " " << mycar.gas_tank ;
std::cout << "录入完成" << std::endl;
return 0;
}