第九讲:编译预处理命令

编译预处理命令

1.#include 包含指令
将一个源文件嵌入到当前源文件中该点处。
#include<文件名>  
按标准方式搜索,文件位于C++系统目录的include子目录下
#include"文件名"
首先在当前目录中搜索,若没有,再按标准方式搜索。
2.#define 宏定义指令
定义符号常量,很多情况下已被const定义语句取代。
定义带参数宏,已被内联函数取代。
#undef
删除由#define定义的宏,使之不再起作用。
3.条件编译指令    #if 和 #endif1#if  常量表达式
 //当“ 常量表达式”非零时编译
     程序正文  
#endif
......
条件编译指令——#else2#if   常量表达式
     //当“ 常量表达式”非零时编译
       程序正文1
#else
  //当“ 常量表达式”为零时编译
       程序正文2
#endif
条件编译指令    #elif3#if 常量表达式1
    程序正文1  //当“ 常量表达式1”非零时编译
#elif 常量表达式2
    程序正文2  //当“ 常量表达式2”非零时编译
#else
    程序正文3  //其他情况下编译
#endif
条件编译指令
(4#ifdef 标识符
    程序段1
#else
    程序段2
#endif
如果“标识符”经#defined定义过,且未经undef删除,则编译程序段1,否则编译程序段2。
条件编译指令
(5)
#ifndef 标识符
   程序段1
#else
   程序段2
#endif
如果“标识符”未被定义过,则编译程序段1,否则编译程序段2

多文件结构

一个源程序可以划分为多个源文件:
类声明文件(.h文件)
类实现文件(.cpp文件)
类的使用文件(main()所在的.cpp文件)
利用工程来组合各个文件。

不使用条件编译的头文件
//main.cpp
#include "file1.h"
#include "file2.h"
int main()
{
    …
}

//file1.h
#include "head.h"//file2.h
#include "head.h"//head.hclass Point
{
    …
}
    …

使用条件编译的头文件
//head.h
#ifndef  HEAD_H
  #define  HEAD_H
    …
  class Point
  {
      …
  }
      …
#endif

三、对象数组
1、对象数组的概念
数组是同类数据的集合;
数组不仅可以由简单变量组成,也可以由用户定义的类对象组成,即每一个数组元素都是同类的对象。
例如:一个班有30人,每个学生的信息包括学号、姓名、性别。先建立起学生类,再对每个学生建立一个对象,需要分别取30个对象名。较好的做法是,定义一个“学生类”的对象数组,每一个数组元素是一个“学生类”的对象。
如: Stud st[30];
2、对象数组的构造函数
①在建立对象数组时,同样调用构造函数。
②如果构造函数只有一个参数,在定义数组时可以在等号后面花括号内提供实参。
如:Stud st[3]={60,70,80};
实参个数不能超过数组元素个数,因为编译系统.只为每个对象元素的构造函数传递一个实参.
如:Stud st[3]={60,70,80,90};//不合法
③如果构造函数有多个参数,则不能用在定义数组时直接提供所有实参的方法。 例如:
Stud::Stud( int =100,int=18,int=60) //构造函数
Stud st[3]={111,34,31};
// 这种使用方式关系不清晰,出现歧义性.
④构造函数有多个参数时,可用如下方法实现对数组对象的初始化.
如: Stud St[3]={
Stud(11,32,74), //调用第1个元素的构造函数,为它提供3个实参。
Stud(12,34,27), //调用第2个元素的构造函数,为它提供3个实参。
Stud(14,45,63) //调用第3个元素的构造函数,为它提供3个实参。
};


#include  // // 例
#include 
using namespace std;
class stud  //定义类
{private:
    int num;    string name;
    char sex;
 public:
    stud( int n, string nam, char s )
    {num = n;  name=nam;
      sex = s;
      cout <<"Constructor called."
              <void display ( );
};


void stud::display ( )
{cout<<"num:"<cout<<"name:"<cout<<"sex:";
 if (sex==0) { cout<<"男"<else { cout<<"女"<int main( )
{stud st[3] = {
   stud(1001,"张三",1),
   stud(1002,"李四",0),
   stud(1003,"王五",0)
 };    //  用指定参数的构造函数初始化数组
 cout <<"第一个学生:" ; st[0].display( );
 cout <<"第二个学生:" ; st[1].display( );
 cout <<"第三个学生:" ; st[2].display( );
return 0;}

例: 对象数组(一维)、构造函数、析构函数应用

#include  //  例(补充)
#include 
using namespace std;
class stud  //定义类
{private:
    int num;    string name;
    char sex;
 public:
    stud( int n, string nam, char s )
    {num = n;  name=nam;
      sex = s;
      cout <"  Constructor called."
              <cout<"  pass"<void display (   );
};
void stud::display ( )
{cout<<"num:"<cout<<"name:"<cout<<"sex:";
 if (sex==0) { cout<<"男"<else { cout<<"女"<int  main( )
{stud st[3] = {
   stud(1001,"张三",1),
   stud(1002,"李四",0),
   stud(1003,"王五",0)
 };    //  用指定参数的构造函数初始化数组
 stud ss(888,"aaa",1);
 ss.display();
 cout <<"第一个学生:" ; st[0].display( );
 cout <<"第二个学生:" ; st[1].display( );
 cout <<"第三个学生:" ; st[2].display( );
return  0;
}

例: 对象数组(二维)、构造函数、析构函数应用

#include  //  例 (补充)
#include 
using namespace std;
class stud  //定义类
{private:
    int num;    string name;
    char sex;
 public:
    stud( int n, string nam, char s )
    {num = n;  name=nam;
      sex = s;
      cout <"  Constructor called."
              <cout<"  pass"<void display (   );
};
void stud::display ( )
{cout<<"num:"<cout<<"name:"<cout<<"sex:";
 if (sex==0) { cout<<"男"<else { cout<<"女"<int  main( )
{stud st[3][2] = {
    {stud(1001,"张三",1),
        stud(1002,"李四",0)},
    {stud(1003,"王五",0),
    stud(1111,"三",1)},
    {stud(2222,"四",0),
    stud(3333,"五",0)}
 };    //  用指定参数的构造函数初始化数组
 stud ss(888,"aaa",1);
 ss.display();
 cout <<"第一个学生:" ; st[0][0].display( );
 cout <<"第二个学生:" ; st[1][0].display( );
 cout <<"第三个学生:" ; st[2][0].display( );
return  0;}



3.4对象数组
例:3.6-1.cpp对象数组和构造函数应用2

#include // 例3.6-1
using namespace std;
class Box   // 类定义
 {public:
   Box(int h=10,int w=12,int len=15)
   { height=h; width=w; length=len; }
   int volume();
  private:
     int height, width, length;
    }; 
 int Box::volume()
  { return (height*width*length);  }
int main()
 {  Box a[3]={
       Box(10,12,15),
       Box(15,18,20),
       Box(16,20,26) };
//  用指定参数的构造函数初始化数组
  cout<<"volume of a[0] is "<0].volume()<cout<<"volume of a[0] is "<1].volume()<cout<<"volume of a[0] is "<2].volume()<return 0;
 }



4对象指针

1、指向对象的指针
创建一个类的对象时,系统会为每一个对象分配一定的存储空间,以存放成员。对象空间的起始地址就是对象的指针。可以定义一个指针,用来存放对象的指针。
定义对象指针格式: 类名 *对象指针名;
例如:time *pt , t;
pt=&t1; // 指针指向对象
利用对象指针访问对象和对象成员的方法:
① *pt //pt所指对象
② ( *pt ).hour 或者:pt->hour //pt所指对象的数据成员
③ (*pt).put ( ) 或者:pt->put( ) //pt所指对象的成员函数


#include 
class Time  //类定义
{public:
   int hour, minute, sec;
   void put ( )
   { hour = 12;
      minute = 0;
      sec = 0;
   }
};

void main ( )
{Time *pt, t1;
 pt = &t1;    // 指针指向对象
 pt->put( );
 cout<hour<<":"<minute
         <<":"<sec<cout<<(*pt).hour<<":"<<(*pt).minute
         <<":"<<(*pt).sec<

2、指向对象数据成员的指针
定义一个指向对象数据成员的指针变量的方法和定义指向普通变量的指针变量方法相同。
定义格式:数据类型名 * 指针变量名;
例如:int *pl; // 定义指向整型数据的指针变量
pl=&t1.hour; // hour必须是公用数据成员
// 将t1的数据成员hour地址赋给指针pl,使其指向t1.hour
cout << *pl <

#include //例
class Time  // 类定义
{public:
   int hour, minute, sec;
   Time ( int h, int m, int s )
   { hour = h;
     minute = m;
     sec = s;
   }
   void get_Time( )
   { cout << hour<<":"
              << minute<<":"
              << sec<int main ( )
{Time t1( 10,13,56 );  
 int *p1 = &t1.hour; 
// 定义指向整形数据的指针,指向t1.hour
 cout << *p1 <// 调用t1的成员函数
 Time  *p2 = &t1;
 // 定义指向Time类对象的指针变量p2,并指向t1
 p2->get_Time( ); //调用p2所指对象的成员函数
 void (Time::*p3)( );
 // 定义指向Time类公用成员函数的指针变量p3
 p3 = &Time::get_Time; 
 // 使p3指向Time类公用成员函数get_Time( )
 (t1.*p3) ( ); //调用p3所指的成员函数t1.get_Time( )
 return 0;
}




```c++

3this 指针
        每个对象中的数据成员分别占有存储空间,如果对同一个类定义n个对象,则有n组同样大小的空间存放n个对象的数据成员。但多个同类对象在内存中是共享成员函数代码以节省内存空间。那么,不同对象的成员函数引用数据成员时,怎么找到自己的数据成员呢?
        C++在每一个成员函数中都包含一个特殊的指针,这个指针的名字是固定的,称为“this”。它是指向本对象的指针,它的值是当前被调用的成员函数所在对象的起始地址。
        例如:当a的成员函数调用数据成员a.volume时,编译系统就把对象a的起始地址赋给 this 指针,于是在成员函数引用数据成员时,就按照 this 的指向找到对象a 的数据成员。




<div class="se-preview-section-delimiter">div>
例如:下列涉及数据成员的运算的返回语句:
    return length*width*height ;
实际上C++处理为:
    return ( this ->length)*(this->width)*(this->height);
也可以写成如下形式:
    return ((*this).length*(*this).width*(*this).height);
但不能写成:
    return ((*this.length) *(*this.width)*(*this.height)); //错误
因为“.”操作符的优先级高于指针运算符“*”,(*this.length)就相当于*(this.length),而 this.length 是不合法的,编译出错(应该是this->length),*this表示this所指的对象。

include

你可能感兴趣的:(c++)