沥林网站制作,织梦网站安装视频教程,广告发布服务包括哪些,wordpress5.2 php版本C 编程指南 ■ C环境安装■ C 基本语法■ 预定义宏■ # 和 ## 运算符■ C 引用■ C 命名空间■ 定义命名空间■ using 指令■ 嵌套的命名空间 ■ String类■ 类■ 类的static静态成员 ■ C 继承■ 继承类型 public、protected 或 private■ 访问控制和继承■ 多继承■ 数据抽象… C 编程指南 ■ C环境安装■ C 基本语法■ 预定义宏■ # 和 ## 运算符■ C 引用■ C 命名空间■ 定义命名空间■ using 指令■ 嵌套的命名空间 ■ String类■ 类■ 类的static静态成员 ■ C 继承■ 继承类型 public、protected 或 private■ 访问控制和继承■ 多继承■ 数据抽象 ■ C 指针■ this 指针■ 指向类的指针 ■ 内联函数■ 构造 析构函数■ 构造函数■ 析构函数■ 拷贝构造函数 ■ 友元■ 友元类■ 友元函数 ■ C 函数重载■ C 多态■ 静态多态或静态链接■ 动态链接或后期绑定 ■ 虚函数■ 纯虚函数 ■ C 标准流文件流■ C 异常处理■ C 动态内存■ C 模板■ 函数模板■ 类模板 ■ C 信号处理■■ ■ C 多线程■■ ■ C 标准库■■ ■ C环境安装
C环境安装
■ C 基本语法
■ 预定义宏
宏描述LINE这会在程序编译时包含当前行号。FILE这会在程序编译时包含当前文件名。DATE这会包含一个形式为 month/day/year 的字符串它表示把源文件转换为目标代码的日期。TIME这会包含一个形式为 hour:minute:second 的字符串它表示程序被编译的时间。
#include iostream
using namespace std;
int main ()
{cout Value of __LINE__ : __LINE__ endl;cout Value of __FILE__ : __FILE__ endl;cout Value of __DATE__ : __DATE__ endl;cout Value of __TIME__ : __TIME__ endl; return 0;
}当上面的代码被编译和执行时它会产生下列结果
Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48■ # 和 ## 运算符
■ C 引用
int i 17;
int r i; //为 i 声明引用变量
double s d; r 14; //引用使用■ C 命名空间
■ 定义命名空间
namespace namespace_name {// 代码声明
}使用命名空间变量或函数
name::code; // code 可以是变量或函数示例一
#include iostream
using namespace std;// 第一个命名空间
namespace first_space{void func(){cout Inside first_space endl;}
}
// 第二个命名空间
namespace second_space{void func(){cout Inside second_space endl;}
}
int main ()
{ // 调用第一个命名空间中的函数first_space::func();// 调用第二个命名空间中的函数second_space::func(); return 0;
}
它会产生下列结果
Inside first_space
Inside second_space■ using 指令
使用 using namespace 指令这样在使用命名空间时就可以不用在前面加上命名空间的名称。 这个指令会告诉编译器后续的代码将使用指定的命名空间中的名称。
#include iostream
using namespace std;// 第一个命名空间
namespace first_space{void func(){cout Inside first_space endl;}
}
// 第二个命名空间
namespace second_space{void func(){cout Inside second_space endl;}
}
using namespace first_space; //这个指令会告诉编译器后续的代码将使用指定的命名空间中的名称。
int main ()
{ // 调用第一个命名空间中的函数func();return 0;
}using 指令也可以用来指定命名空间中的特定项目
using std::cout; //使用 std 命名空间中的 cout 部分示例一使用 std 命名空间中的 cout 部分
#include iostream
using std::cout;int main ()
{cout std::endl is used with std! std::endl;return 0;
}■ 嵌套的命名空间
命名空间可以嵌套
namespace namespace_name1 {// 代码声明namespace namespace_name2 {// 代码声明}
}通过使用 :: 运算符来访问嵌套的命名空间中的成员
// 访问 namespace_name2 中的成员
using namespace namespace_name1::namespace_name2;// 访问 namespace_name1 中的成员
using namespace namespace_name1;示例一嵌套的命名空间使用
#include iostream
using namespace std;// 第一个命名空间
namespace first_space{void func(){cout Inside first_space endl;}// 第二个命名空间namespace second_space{void func(){cout Inside second_space endl;}}
}
using namespace first_space::second_space;
int main ()
{ // 调用第二个命名空间中的函数func(); return 0;
}示例二全局变量 a 表达为 ::a用于当有同名的局部变量时来区别两者。
#include iostream
using namespace std;
namespace A
{int a 100;namespace B //嵌套一个命名空间B{int a 20;}
}int a 200;//定义一个全局变量int main(int argc, char *argv[])
{cout A::a A::a endl;cout A::B::a A::B::a endl;cout a a endl;cout ::a ::a endl;int a 30;cout a a endl;cout ::a ::a endl;return 0;
}
结果
A::a 100
A::B::a 20
a 200 //全局变量a
::a 200
a 30 //局部变量a
::a 200 ■ String类
C 标准库提供了 string 类类型。
示例一
#include iostream
#include stringusing namespace std;int main ()
{string str1 runoob;string str2 google;string str3;int len ;// 复制 str1 到 str3str3 str1;cout str3 : str3 endl;// 连接 str1 和 str2str3 str1 str2;cout str1 str2 : str3 endl;// 连接后str3 的总长度len str3.size();cout str3.size() : len endl;return 0;
}结果
str3 : runoob
str1 str2 : runoobgoogle
str3.size() : 12–
■ 类
■ 类的static静态成员
类的变量和函数都可以被声明为静态的。static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时这意味着无论创建多少个类的对象静态成员都只有一个副本。静态成员在类的所有对象中是共享的。在创建第一个对象时所有的静态数据都会被初始化为零不能把静态成员的初始化放置在类的定义中。在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化
示例一
#include iostreamusing namespace std;class Box
{public:static int objectCount;// 构造函数定义Box(double l2.0, double b2.0, double h2.0){cout Constructor called. endl;length l;breadth b;height h;// 每次创建对象时增加 1objectCount;}double Volume(){return length * breadth * height;}static int getCount(){return objectCount;}private:double length; // 长度double breadth; // 宽度double height; // 高度
};// 初始化类 Box 的静态成员
int Box::objectCount 0;int main(void)
{// 在创建对象之前输出对象的总数cout Inital Stage Count: Box::getCount() endl;Box Box1(3.3, 1.2, 1.5); // 声明 box1Box Box2(8.5, 6.0, 2.0); // 声明 box2// 在创建对象之后输出对象的总数cout Final Stage Count: Box::getCount() endl;return 0;
}
当上面的代码被编译和执行时它会产生下列结果
Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2■ C 继承
已有的类称为基类新建的类称为派生类。
示例一基类 派生类
// 基类
class Animal {// eat() 函数// sleep() 函数
};//派生类
class Dog : public Animal {// bark() 函数
};■ 继承类型 public、protected 或 private
继承类型说明公有继承public当一个类派生自公有基类时基类的公有成员也是派生类的公有成员基类的保护成员也是派生类的保护成员基类的私有成员不能直接被派生类访问但是可以通过调用基类的公有和保护成员来访问。保护继承protected当一个类派生自保护基类时基类的公有和保护成员将成为派生类的保护成员。私有继承private当一个类派生自私有基类时基类的公有和保护成员将成为派生类的私有成员。
■ 访问控制和继承
派生类可以访问基类中所有成员访问权限如下
访问publicprotectedprivate同一个类yesyesyes派生类yesyesno外部的类yesnono
一个派生类继承了所有的基类方法但下列情况除外 基类的构造函数、析构函数和拷贝构造函数。 基类的重载运算符。 基类的友元函数。
■ 多继承
多继承即一个子类可以有多个父类它继承了多个父类的特性。
class 派生类名:继承方式1基类名1,继承方式2基类名2,…
{派生类类体
};// 派生类
class Rectangle: public Shape, public PaintCost
{public:int getArea(){ return (width * height); }
};■ 数据抽象
类的内部受到保护不会因无意的用户级错误导致对象状态受损。 数据抽象是一个把实现细节与相关的数据分离开的概念。
#include iostream
using namespace std;
class Adder{public:// 构造函数Adder(int i 0){total i;}// 对外的接口void addNum(int number){total number;}// 对外的接口int getTotal(){return total;};private:// 对外隐藏的数据int total;
};
int main( )
{Adder a; a.addNum(10);a.addNum(20);a.addNum(30); cout Total a.getTotal() endl;return 0;
}
当上面的代码被编译和执行时它会产生下列结果
Total 60■ C 指针
■ this 指针
this 指针是一个特殊的指针它指向当前对象的实例。 每一个对象都能通过 this 指针来访问自己的地址。 友元函数没有 this 指针因为友元不是类的成员只有成员函数才有 this 指针。
■ 指向类的指针
示例一声明和初始化指向类的指针
#include iostreamclass MyClass {
public:int data;void display() {std::cout Data: data std::endl;}
};
int main() {// 创建类对象MyClass obj;obj.data 42;// 声明和初始化指向类的指针MyClass *ptr obj;// 通过指针访问成员变量std::cout Data via pointer: ptr-data std::endl;// 通过指针调用成员函数ptr-display();return 0;
}示例二动态分配内存
#include iostream
class MyClass {
public:int data;void display() {std::cout Data: data std::endl;}
};int main() {// 动态分配内存创建类对象MyClass *ptr new MyClass;ptr-data 42;// 通过指针调用成员函数ptr-display();// 释放动态分配的内存delete ptr;return 0;
}示例三指向类的指针作为函数参数
#include iostream
class MyClass {
public:int data;void display() {std::cout Data: data std::endl;}
};
// 函数接受指向类的指针作为参数
void processObject(MyClass *ptr) {ptr-display();
}
int main() {MyClass obj;obj.data 42;// 将指向类的指针传递给函数processObject(obj);return 0;
}■ 内联函数
C 内联函数是通常与类一起使用。如果一个函数是内联的那么在编译时编译器会把该函数的代码副本放置在每个调用该函数的地方。 对内联函数进行任何修改都需要重新编译函数的所有客户端因为编译器需要重新更换一次所有的代码否则将会继续使用旧的函数。 如果想把一个函数定义为内联函数则需要在函数名前面放置关键字 inline
内联函数作用 引入内联函数的目的是为了解决程序中函数调用的效率问题。 程序在编译器编译的时候编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换而对于其他的函数都是在运行时候才被替代。这其实就是个空间代价换时间的节省。
内联函数确定
内联那些包含循环或 switch 语句的函数常常是得不偿失 (除非在大多数情况下, 这些循环或 switch 语句从不被执行).有些函数即使声明为内联的也不一定会被编译器内联, 比如虚函数和递归函数就不会被正常内联. 通常, 递归函数不应该声明成内联函数
示例一声明内联函数 inline
#include iostream
using namespace std;inline int Max(int x, int y)
{return (x y)? x : y;
}// 程序的主函数
int main( )
{cout Max (20,10): Max(20,10) endl;cout Max (0,200): Max(0,200) endl;cout Max (100,1010): Max(100,1010) endl;return 0;
}当上面的代码被编译和执行时它会产生下列结果
Max (20,10): 20
Max (0,200): 200
Max (100,1010): 1010■ 构造 析构函数
■ 构造函数
示例一无参构造
class Line
{public:void setLength( double len );double getLength( void );Line(double len); // 这是构造函数private:double length;
};// 成员函数定义包括构造函数
Line::Line( double len)
{cout Object is being created, length len endl;length len;
}
//使用声明
Line line(10.0);示例二使用初始化列表来初始化字段
class Line
{public:void setLength( double len );double getLength( void );Line(double len); // 这是构造函数private:double length;
};
Line::Line( double len): length(len)
{cout Object is being created, length len endl;
}上面的语法等同于如下语法
Line::Line( double len)
{length len;cout Object is being created, length len endl;
}■ 析构函数
class Line
{public:void setLength( double len );double getLength( void );Line(); // 这是构造函数声明~Line(); // 这是析构函数声明private:double length;
};
Line::~Line(void)
{cout Object is being deleted endl;
}// 程序的主函数
int main( )
{Line line;// 设置长度line.setLength(6.0); cout Length of line : line.getLength() endl;return 0;
}
当上面的代码被编译和执行时它会产生下列结果
Object is being created
Length of line : 6
Object is being deleted■ 拷贝构造函数
拷贝构造函数是一种特殊的构造函数它在创建对象时是使用同一类中之前创建的对象来初始化新创建的对象。 拷贝构造函数通常用于
通过使用另一个同类型的对象来初始化新创建的对象。复制对象把它作为参数传递给函数。复制对象并从函数返回这个对象。 如果在类中没有定义拷贝构造函数编译器会自行定义一个。如果类带有指针变量并有动态内存分配则它必须有一个拷贝构造函数。 拷贝构造函数的最常见形式如下
classname (const classname obj) {// 构造函数的主体
}示例一 拷贝构造函数
class Line
{public:int getLength( void );Line( int len ); // 简单的构造函数Line( const Line obj); // 拷贝构造函数~Line(); // 析构函数private:int *ptr;
};
// 成员函数定义包括构造函数
Line::Line(int len)
{cout 调用构造函数 endl;// 为指针分配内存ptr new int;*ptr len;
}Line::Line(const Line obj)
{cout 调用拷贝构造函数并为指针 ptr 分配内存 endl;ptr new int;*ptr *obj.ptr; // 拷贝值
}
Line::~Line(void)
{cout 释放内存 endl;delete ptr; //要记得释放内存
}
int Line::getLength( void )
{return *ptr;
}void display(Line obj)
{cout line 大小 : obj.getLength() endl;
}// 程序的主函数
int main( )
{Line line(10);display(line);return 0;
}
当上面的代码被编译和执行时它会产生下列结果
调用构造函数
调用拷贝构造函数并为指针 ptr 分配内存
line 大小 : 10
释放内存
释放内存#include iostreamusing namespace std;class Line
{public:int getLength( void );Line( int len ); // 简单的构造函数Line( const Line obj); // 拷贝构造函数~Line(); // 析构函数private:int *ptr;
};// 成员函数定义包括构造函数
Line::Line(int len)
{cout 调用构造函数 endl;// 为指针分配内存ptr new int;*ptr len;
}Line::Line(const Line obj)
{cout 调用拷贝构造函数并为指针 ptr 分配内存 endl;ptr new int;*ptr *obj.ptr; // 拷贝值
}Line::~Line(void)
{cout 释放内存 endl;delete ptr;
}
int Line::getLength( void )
{return *ptr;
}void display(Line obj)
{cout line 大小 : obj.getLength() endl;
}// 程序的主函数
int main( )
{Line line1(10); //调用构造函数Line line2 line1; // 这里也调用了拷贝构造函数display(line1); // 这里也调用了拷贝构造函数display(line2); // 这里也调用了拷贝构造函数return 0;
}
当上面的代码被编译和执行时它会产生下列结果调用构造函数
调用拷贝构造函数并为指针 ptr 分配内存
调用拷贝构造函数并为指针 ptr 分配内存
line 大小 : 10
释放内存
调用拷贝构造函数并为指针 ptr 分配内存
line 大小 : 10
释放内存
释放内存
释放内存■ 友元
■ 友元类
整个类及其所有成员都是友元。
■ 友元函数
类的友元函数是定义在类内部但有权访问类的所有私有private成员和保护protected成员。 尽管友元函数的原型有在类的定义中出现过但是友元函数并不是成员函数。 友元函数没有 this 指针因为友元不是类的成员只有成员函数才有 this 指针。 示例一在类定义中函数原型前使用关键字 friend表示这个函数是类的友元函数在函数中可以访问类中的成员函数或成员变量
#include iostream
using namespace std;
class Box
{double width;
public:friend void printWidth( Box box ); //声明友元函数但是友元函数并不是成员函数。void setWidth( double wid );
};// 成员函数定义
void Box::setWidth( double wid )
{width wid;
}// 请注意printWidth() 不是任何类的成员函数
void printWidth( Box box )
{/* 因为 printWidth() 是 Box 的友元它可以直接访问该类的任何成员 */cout Width of box : box.width endl;
}// 程序的主函数
int main( )
{Box box;// 使用成员函数设置宽度box.setWidth(10.0);// 使用友元函数输出宽度printWidth( box );return 0;
}
当上面的代码被编译和执行时它会产生下列结果
Width of box : 10■ C 函数重载
C 函数重载
■ C 多态
多态按字面的意思就是多种形态. 当类之间存在层次结构并且类之间是通过继承关联时就会用到多态。 C 多态意味着调用成员函数时会根据调用函数的对象的类型来执行不同的函数。
■ 静态多态或静态链接
示例一静态多态或静态链接, 有时候这也被称为早绑定
调用函数 area() 被编译器设置为基类中的版本这就是所谓的静态多态或静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定
#include iostream
using namespace std;class Shape {protected:int width, height;public:Shape( int a0, int b0){width a;height b;}int area(){cout Parent class area : endl;return 0;}
};
class Rectangle: public Shape{public:Rectangle( int a0, int b0):Shape(a, b) { }int area (){ cout Rectangle class area : endl;return (width * height); }
};
class Triangle: public Shape{public:Triangle( int a0, int b0):Shape(a, b) { }int area (){ cout Triangle class area : endl;return (width * height / 2); }
};
// 程序的主函数
int main( )
{Shape *shape;Rectangle rec(10,7);Triangle tri(10,5);// 存储矩形的地址shape rec;// 调用矩形的求面积函数 areashape-area();// 存储三角形的地址shape tri;// 调用三角形的求面积函数 areashape-area();return 0;
}
当上面的代码被编译和执行时它会产生下列结果
Parent class area :
Parent class area :■ 动态链接或后期绑定
在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时会告诉编译器不要静态链接到该函数。这种操作被称为动态链接或后期绑定。 示例一声明前放置关键字 virtual
*此时编译器看的是指针的内容而不是它的类型。因此由于 tri 和 rec 类的对象的地址存储在 shape 中 所以会调用各自的 area() 函数。
class Shape {protected:int width, height;public:Shape( int a0, int b0){width a;height b;}virtual int area() //添加virtual变成虚函数{cout Parent class area : endl;return 0;}
};
修改后当编译和执行前面的实例代码时它会产生以下结果
Rectangle class area :
Triangle class area :■ 虚函数
虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时会告诉编译器不要静态链接到该函数。
■ 纯虚函数
基类中定义虚函数以便在派生类中重新定义该函数更好地适用于对象但是您在基类中又不能对虚函数给出有意义的实现这个时候就会用到纯虚函数。 **
示例一virtual int area() 0; 告诉编译器函数没有主体上面的虚函数是纯虚函数。
class Shape {protected:int width, height;public:Shape( int a0, int b0){width a;height b;}// pure virtual functionvirtual int area() 0; // 0 告诉编译器函数没有主体上面的虚函数是纯虚函数。
};■ C 标准流文件流
C 标准流文件流
■ C 异常处理
C 异常处理
■ C 动态内存
malloc() 函数在 C 语言中就出现了在 C 中仍然存在 new 与 malloc() 函数相比其主要的优点是new 不只是分配了内存它还创建了对象。
动态分配,一维数组
// 动态分配,数组长度为 m
int *arraynew int [m];//释放内存
delete [] array;动态分配,二维数组
int **array;
// 假定数组第一维长度为 m 第二维长度为 n
// 动态分配空间
array new int *[m];
for( int i0; im; i )
{array[i] new int [n];
}
//释放
for( int i0; im; i )
{delete [] array[i];
}
delete [] array;动态分配,三维数组
int ***array;
// 假定数组第一维为 m 第二维为 n 第三维为h
// 动态分配空间
array new int **[m];
for( int i0; im; i )
{array[i] new int *[n];for( int j0; jn; j ){array[i][j] new int [h];}
}
//释放
for( int i0; im; i )
{for( int j0; jn; j ){delete[] array[i][j];}delete[] array[i];
}
delete[] array;对象的动态内存分配
#include iostream
using namespace std;class Box
{public:Box() { cout 调用构造函数 endl; }~Box() { cout 调用析构函数 endl; }
};int main( )
{Box* myBoxArray new Box[4];delete [] myBoxArray; // 删除数组return 0;
}■ C 模板
■ 函数模板
示例一
#include iostream
#include string
using namespace std;template typename T
inline T const Max (T const a, T const b)
{ return a b ? b:a;
}
int main ()
{ int i 39;int j 20;cout Max(i, j): Max(i, j) endl; double f1 13.5; double f2 20.7; cout Max(f1, f2): Max(f1, f2) endl; string s1 Hello; string s2 World; cout Max(s1, s2): Max(s1, s2) endl; return 0;
}
当上面的代码被编译和执行时它会产生下列结果
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World■ 类模板
示例一类模板
#include iostream
#include vector
#include cstdlib
#include string
#include stdexceptusing namespace std;template class T
class Stack { private: vectorT elems; // 元素 public: void push(T const); // 入栈void pop(); // 出栈T top() const; // 返回栈顶元素bool empty() const{ // 如果为空则返回真。return elems.empty(); }
}; template class T
void StackT::push (T const elem)
{ // 追加传入元素的副本elems.push_back(elem);
} template class T
void StackT::pop ()
{ if (elems.empty()) { throw out_of_range(Stack::pop(): empty stack); }// 删除最后一个元素elems.pop_back();
} template class T
T StackT::top () const
{ if (elems.empty()) { throw out_of_range(Stack::top(): empty stack); }// 返回最后一个元素的副本 return elems.back();
} int main()
{ try { Stackint intStack; // int 类型的栈 Stackstring stringStack; // string 类型的栈 // 操作 int 类型的栈 intStack.push(7); cout intStack.top() endl; // 操作 string 类型的栈 stringStack.push(hello); cout stringStack.top() std::endl; stringStack.pop(); stringStack.pop(); } catch (exception const ex) { cerr Exception: ex.what() endl; return -1;}
}
它会产生下列结果
7
hello
Exception: Stack::pop(): empty stack■ C 信号处理
■
■
■ C 多线程
■
■
■ C 标准库
■
■