前言 本来是准备一直更新Go语言笔记的了,但是突然发现CAPE-OPEN好像只能用C++语言来写(官方说也可以用VB,但是我觉得吧,VB就算了)
因为CAPE-OPEN应该是要进行COM组件的注册以及操作的,故C++较为适宜,当然Java也是可以的,但是不推荐,理论上支持COM组件 以及可以编译为动态链接库 的语言都是可以的
所以又得继续拾起C++了,so,开始学习吧骚年,加油!
Hello World 1 2 3 4 5 #include <iostream> int main () { std::cout << "Hello World!" << std::endl; return 0 ; }
基础语法 现在我们通过解析上述的例子来学习一下C++程序的语法
首先第一行 #include <iostream>
是引入C++的标准库 iostream
,以用来可以输入/出信息,从库名字也可以看出来,I/O
和 stream
就是输入/出信息流嘛;如果要引入一些本地库或第三方库,可以通过使用 #include "[path]"
格式,其中 path
就是头文件/库所在的路径。
第二行 int main() { }
是主函数,程序从这里开始执行,int
是函数类型,main()
是函数名称和传入参数,函数内容放在大括号中。
第三行 std::cout << "Hello World!" << std::endl;
是在屏幕中输出信息,其中 std::
这是个名称空间标示符,是用来声明使用的是标准库中的函数/对象,以防止出现同名的函数/对象产生冲突;
<<
符号在cpp中既可以用来执行位运算,又可以做输入/出流,<<
和 cout
一起使用就是输出,cin
和 >>
一起使用就是输入;
双引号表示字符串就不用说了,后面的 endl
是换行符,这里进行了简略缩写,实际上可以写成如下所示:
1 2 3 4 std::cout << "Hello World!" ; std::cout << std::endl; std::cout << "Hello World!" ; std::cout << std::endl;
在这里可以看到,C++并不是以行末为语句的结束的,而是以 ;
分号为准的。
第四行 return 0;
一般用作表示程序的结束,实际上这个语句根据函数类型的不同而不同,而且 return 0;
在不同的情境下可能含义也是不同的,这个之后再进行深究。
C++标准库(C++ Standard Library),是类库和函数的集合,其使用核心语言写成,由C++标准委员会制定,并不断维护更新。C++强大的功能来源于其丰富的类库及库函数资源。在C++开发中,要尽可能地利用标准库完成,这样可以降低成本,提高编程效率,保证程序质量,又能保持编程风格一致性。C++标准库又分为标准函数库和面向对象类库。
标准函数库包括: 输入/输出IO、字符串和字符处理、数学、时间、日期和本地化、动态分配、其他、宽字符函数。
面向对象类库包括: 标准的C++ IO类、String类、数值类、STL容器类、STL算法、STL函数对象、STL迭代器、STL分配器、本地化库、异常处理类、杂项支持库。
哦对,别忘了注释格式哦:
声明命名空间 在上述例子中,可以看到大量且频繁的使用 std::
命名空间标示符,是比较繁琐的,实际上有一种简单的声明方式可以解决:
1 2 3 4 5 6 7 8 #include <iostream> using namespace std; int main () { cout << "Hello World!" << endl; return 0 ; }
通过命名空间的声明,可以默认该程序内部使用的都是该库下的函数/对象;也可以只声明需要使用的部分:
1 2 3 4 5 6 7 8 #include <iostream> using std::cout; int main () { cout << "Hello World!" << std::endl; return 0 ; }
当然,命名空间是可以自定义的,格式如下:
1 2 3 4 5 6 7 namespace [namespaceName] { } [namespaceName]::<code>;
举个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> namespace first_space { void funcTest () { std::cout << "Inside first_space" << std::endl; } } namespace second_space { void funcTest () { std::cout << "Inside second_space" << std::endl; } } int main () { first_space::funcTest (); second_space::funcTest (); return 0 ; }
执行结果:
可以看到,调用指定命名空间中的函数需要在函数前增加命名空间标示符,这样即使出现同名函数,也不会互相冲突,所以在实际开发过程中,是非常推荐使用命名空间标示符的,再举个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream> namespace first_space { void funcTest () { std::cout << "Inside first_space" << std::endl; } } namespace second_space{ void funcTest () { std::cout << "Inside second_space" << std::endl; } } using namespace first_space; int main () { funcTest (); return 0 ; }
执行结果:
可以看到,在主函数 main()
前面进行了命名空间的声明,所以主函数中的同名函数 funcTest()
执行输出的结果是第一个命名空间中的函数,当然C++程序执行时有严格的顺序要求,如果将命名空间的注册语句或者使用语句放在main函数后,那么就会报错 ,例如:
请严格记住,C++程序的执行顺序必然是从上到下,所以主函数 main()
中的其他函数、变量、方法、对象等必须在主函数前进行注册或声明。
同样,函数中的语句也是要严格遵守这一点的。
变量与常量 数据类型 C++七大基本类型:
其中的 wchar_t
其实是利用了 typedef
声明,使用方法如下:
1 2 3 4 5 6 7 typedef <type> <newname> typedef short int wchar_t ;typedef int feet; feet test;
一些基本类型可以使用一个或多个类型修饰符进行修饰:
1 signed unsigned short long
默认情况下,int、short、long都是带符号的,即signed
具体的占用空间大小和长度就不赘述了,下面这个例子可以直接体现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> #include <limits> using namespace std;int main () { cout << "type: \t\t" << "************size**************" << endl; cout << "bool: \t\t" << "所占字节数:" << sizeof (bool ); cout << "\t最大值:" << (numeric_limits<bool >::max)(); cout << "\t\t最小值:" << (numeric_limits<bool >::min)() << endl; cout << "char: \t\t" << "所占字节数:" << sizeof (char ); cout << "\t最大值:" << (numeric_limits<char >::max)(); cout << "\t\t最小值:" << (numeric_limits<char >::min)() << endl; cout << "signed char: \t" << "所占字节数:" << sizeof (signed char ); cout << "\t最大值:" << (numeric_limits<signed char >::max)(); cout << "\t\t最小值:" << (numeric_limits<signed char >::min)() << endl; cout << "unsigned char: \t" << "所占字节数:" << sizeof (unsigned char ); cout << "\t最大值:" << (numeric_limits<unsigned char >::max)(); cout << "\t\t最小值:" << (numeric_limits<unsigned char >::min)() << endl; cout << "wchar_t: \t" << "所占字节数:" << sizeof (wchar_t ); cout << "short: \t\t" << "所占字节数:" << sizeof (short ); cout << "\t最大值:" << (numeric_limits<short >::max)(); cout << "\t\t最小值:" << (numeric_limits<short >::min)() << endl; cout << "int: \t\t" << "所占字节数:" << sizeof (int ); cout << "\t最大值:" << (numeric_limits<int >::max)(); cout << "\t最小值:" << (numeric_limits<int >::min)() << endl; cout << "unsigned: \t" << "所占字节数:" << sizeof (unsigned ); cout << "\t最大值:" << (numeric_limits<unsigned >::max)(); cout << "\t最小值:" << (numeric_limits<unsigned >::min)() << endl; cout << "long: \t\t" << "所占字节数:" << sizeof (long ); cout << "\t最大值:" << (numeric_limits<long >::max)(); cout << "\t最小值:" << (numeric_limits<long >::min)() << endl; cout << "unsigned long: \t" << "所占字节数:" << sizeof (unsigned long ); cout << "\t最大值:" << (numeric_limits<unsigned long >::max)(); cout << "\t最小值:" << (numeric_limits<unsigned long >::min)() << endl; cout << "double: \t" << "所占字节数:" << sizeof (double ); cout << "\t最大值:" << (numeric_limits<double >::max)(); cout << "\t最小值:" << (numeric_limits<double >::min)() << endl; cout << "long double: \t" << "所占字节数:" << sizeof (long double ); cout << "\t最大值:" << (numeric_limits<long double >::max)(); cout << "\t最小值:" << (numeric_limits<long double >::min)() << endl; cout << "float: \t\t" << "所占字节数:" << sizeof (float ); cout << "\t最大值:" << (numeric_limits<float >::max)(); cout << "\t最小值:" << (numeric_limits<float >::min)() << endl; cout << "size_t: \t" << "所占字节数:" << sizeof (size_t ); cout << "\t最大值:" << (numeric_limits<size_t >::max)(); cout << "\t最小值:" << (numeric_limits<size_t >::min)() << endl; cout << "string: \t" << "所占字节数:" << sizeof (string) << endl; cout << "type: \t\t" << "************size**************" << endl; return 0 ; }
输出如下:
枚举类型: 是C++中的一种派生数据类型,它是由用户定义的若干枚举常量的集合。如果一个变量只有几种可能的值,可以定义为枚举(enumeration)类型。所谓”枚举”是指将变量的值一一列举出来,变量的值只能在列举出来的值的范围内。
用法:
1 2 3 4 5 enum 枚举名{ 标识符[=整型常数], 标识符[=整型常数], 标识符[=整型常数] } 枚举变量;
如果枚举没有初始化, 即省掉 =整型常数
时, 则从第一个标识符开始。
默认情况下,第一个名称的值为 0,第二个名称的值为 1,第三个名称的值为 2,以此类推
举个例子:
1 2 3 enum color { red, green, blue } c;c = blue;
在该示例中,red
的值为 0
、green
的值为 1
、blue
的值为 2
当然也可以给名称直接赋予值,例如:
1 2 3 4 5 6 enum color { red, green = 6 , blue } c; c = blue;
此时,red
的值依然为 0
,但是 green
的值为 6
,同时 blue
的值自增1,为 7
类型转换 C++中有四种类型转换:静态转换、动态转换、常量转换和重新解释转换。
静态转换(Static Cast):
静态转换是将一种数据类型的值强制转换为另一种数据类型的值,通常用于比较类型相似的对象之间的转换,例如将 int
类型转换为 float
类型。静态转换不进行任何运行时类型检查,因此可能会导致运行时错误。
1 2 3 int a = 10 ;float b = static_cast <float >(a);
动态转换(Dynamic Cast):
动态转换通常用于将一个基类指针或引用转换为派生类指针或引用。动态转换在运行时进行类型检查,如果不能进行转换则返回空指针或引发异常。
1 2 3 4 5 class Base {};class Derived : public Base {};Base* ptr_base = new Derived; Derived* ptr_derived = dynamic_cast <Derived*>(ptr_base);
什么是指针后续再讲,这里先不做具体描述
常量转换(Const Cast):
常量转换用于将 const
类型的对象转换为 非const
类型的对象,且只能用于转换掉const属性,不能改变对象的类型 。
1 2 3 const int a = 10 ;int & b = const_cast <int &>(a);
重新解释转换(Reinterpret Cast):
重新解释转换将一个数据类型的值重新解释为另一个数据类型的值,通常用于在不同的数据类型之间进行转换。
重新解释转换不进行任何类型检查,因此可能会导致未定义的行为。
1 2 3 int a = 10 ;float b = reinterpret_cast <float &>(a);
变量类型 变量其实只不过是程序可操作的存储区的名称,在C++中,有多种变量类型可用于存储不同种类的数据。
C++中每个变量都有指定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。
变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头,且大写字母和小写字母是不同的。
C++常见的变量类型有如下几种:
整数类型:int
short
long
long long
;用于表示整数、短整数、长整数、更长整数。
浮点类型:float
double
long double
;用于表示单精度、双精度、更高精度的浮点数。
字符类型:char
wchar_t
char16_t
char32_t
;用于表示字符、宽字符、16位Unicode字符、32位Unicode字符。
布尔类型:bool
;用于表示布尔值,只能取true或false。
枚举类型:enum
;用于定义一组命名的整数常量。
指针类型:type*
,type
是其他的类型;用于表示指向类型为type的对象的指针。
数组类型:type[]
或 type[size]
;用于表示具有相同类型的元素组成的数组。
结构体类型:struct
;用于定义包含多个不同类型成员的结构。
类 类型:class
;用于定义具有属性和方法的自定义类型。
共用体类型:union
;用于定义一种特殊的数据类型,它可以在相同的内存位置存储不同的数据类型。
每种类型占用多少字节不赘述
变量定义与声明 举例:
1 2 3 4 5 6 7 8 int i, j, k;char c, ch;float f, salary;double d;extern int d = 3 , f = 5 ; int d = 3 , f = 5 ; byte z = 22 ; char x = 'x' ;
关键字 extern
是用来引用在函数后面或另一个文件中的变量
变量赋值举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <iostream> using namespace std;extern int a, b; extern int c;extern float f;int main () { int a, b; int c; float f; a = 10 ; b = 20 ; c = a + b; cout << c << endl; f = 70.0 /3.0 ; cout << f << endl ; return 0 ; }
可以看到在C++中,赋值是右值赋给左值,左值可以为变量,执行结果:
同样的,在函数声明时,提供一个函数名,而函数的实际定义则可以在任何地方进行,例如:
1 2 3 4 5 6 7 8 9 10 #include <iostream> using namespace std;int func () ; int main () { int i = func (); cout << i << endl; } int func () { return 0 ; }
执行结果:
但是如果在main函数之前没有进行变量/函数声明,而直接在main函数中进行调用的话,是调用不到的且编译会报错,例如:
1 2 3 4 5 6 7 8 9 #include <iostream> using namespace std;int main () { int i = func (); cout << i << endl; } int func () { return 0 ; }
执行结果:
但是可以把函数定义放在函数调用之前即可:
1 2 3 4 5 6 7 8 9 #include <iostream> using namespace std;int func () { return 0 ; } int main () { int i = func (); cout << i << endl; }
这样就可以成功调用了,变量也是同理,在实际开发过程中,我们推荐在main函数前先给函数/变量声明,再在main函数之后进行定义,会使代码更加工整。
变量作用域 一般来说有三个地方可以定义变量:
在函数或一个代码块内部声明的变量,称为局部变量 ;
在函数参数的定义中声明的变量,称为形式参数 ;
在所有函数外部声明的变量,称为全局变量 。
作用域是程序的一个区域,变量的作用域可以分为以下几种:
局部作用域: 在函数内部声明的变量具有局部作用域,它们只能在函数内部访问。局部变量在函数每次被调用时被创建,在函数执行完后被销毁;
全局作用域: 在所有函数和代码块之外声明的变量具有全局作用域,它们可以被程序中的任何函数访问。全局变量在程序开始时被创建,在程序结束时被销毁;
块作用域: 在代码块内部声明的变量具有块作用域,它们只能在代码块内部访问。块作用域变量在代码块每次被执行时被创建,在代码块执行完后被销毁;
类作用域: 在类内部声明的变量具有类作用域,它们可以被类的所有成员函数访问。类作用域变量的生命周期与类的生命周期相同。
如果在内部作用域中声明的变量与外部作用域中的变量同名,则内部作用域中的变量将覆盖外部作用域中的变量
局部变量:
在函数或一个代码块内部声明的变量,称为局部变量,只能被函数内部或者代码块内部的语句使用:
1 2 3 4 5 6 7 8 9 10 11 #include <iostream> using namespace std;int main () { int a, b; int c; a = 10 ; b = 20 ; c = a + b; cout << c << endl; return 0 ; }
全局变量:
在所有函数外部定义的变量(通常是在程序的头部),称为全局变量,可以被任何函数访问,也就是说,全局变量一旦声明,在整个程序中都是可用的:
1 2 3 4 5 6 7 8 9 10 11 #include <iostream> using namespace std;int g; int main () { int a, b; a = 10 ; b = 20 ; g = a + b; cout << g << endl; return 0 ; }
局部变量和全局变量的名称可以相同,但是在函数内,局部变量 的值会覆盖全局变量的值:
1 2 3 4 5 6 7 8 #include <iostream> using namespace std;int g = 20 ; int main () { int g = 10 ; cout << g << endl; return 0 ; }
执行结果:
初始化局部变量和全局变量:
当局部变量被定义时,系统不会对其初始化,必须自行对其初始化。定义全局变量时,系统会自动初始化为下列值:
int
:0;char
:’\0’;float
:0;double
:0;pointer
:NULL;
块作用域指的是在代码块内部声明的变量,例:
1 2 3 4 5 6 7 8 9 10 11 #include <iostream> using namespace std;int main () { int a = 10 ; { int a = 20 ; cout << "块变量: " << a << endl; } cout << "外部变量: " << a << endl; return 0 ; }
执行结果:
类作用域:
类作用域指的是在类内部声明的变量,例:
1 2 3 4 5 6 7 8 9 10 #include <iostream> class MyClass { public : static int class_var; }; int MyClass::class_var = 30 ;int main () { std::cout << "类变量: " << MyClass::class_var << std::endl; return 0 ; }
执行结果:
什么是类,后续再说
常量 常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。常量可以是任何的基本数据类型,可分为整型数字、浮点数字、字符、字符串和布尔值。常量就像是常规的变量,只不过常量的值在定义后不能进行修改。
在C++中,有两种简单的定义常量的方式:
使用#define预处理器:
1 #define [identifier] [value]
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> using namespace std;#define LENGTH 10 #define WIDTH 5 #define NEWLINE '\n' int main () { int area; area = LENGTH * WIDTH; cout << area; cout << NEWLINE; cout << area; return 0 ; }
执行结果:
\n
被执行了
使用const关键字:
1 const [type] [variable] = [value];
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> using namespace std;int main () { const int LENGTH = 10 ; const int WIDTH = 5 ; const char NEWLINE = '\n' ; int area; area = LENGTH * WIDTH; cout << area; cout << NEWLINE; cout << area; return 0 ; }
执行结果同上,这里需要注意的是,使用 const
关键字并不是一定需要放在函数内部,它可以和 #define
一样作为全局变量来使用
一般来说,在开发过程中把常量定义为全大写字母形式