c++ 基础入门
简介:c++是一种高级语言,C++ 是一种高级语言,它是由 Bjarne Stroustrup 于 1979 年在贝尔实验室开始设计开发的。C++ 进一步扩充和完善了 C 语言,是一种面向对象的程序设计语言。C++ 可运行于多种平台上,如 Windows、MAC 操作系统以及 UNIX 的各种版本。
本教程适合拥有c语言基础的同学,主打一个动手和快速入门
关于c++
c++是一种大小敏感的语言,支持面向对象和面向过程编程。
c++被认为是一种中级语言,因为它综合了高级语言和低级语言的特点。
c++是c语言的一个超集,类似包含关系,所以,任何合法的c程序都是合法的c++程序。
注意: 使用静态类型的编程语言是在编译时执行类型检查,而不是在运行时执行类型检查。
c++的用途十分的广泛,得益于它的高性能,非常适合算法,参加竞赛推荐使用c++语言
c++因为其高效的性能和对硬件的直接控制能力,广泛应用于游戏开发,嵌入式系统开发,金融领域,图形图像处理,科学计算和数值分析等领域,著名游戏引擎就是用unity编写的,各种智能手机,机器人和家电领域也普遍采用高性能的c++语言
c++基础语法
c++基础语言与c语言非常的类似,在这里只列举与c语言的最根本区
-
数据类型:c++的数据类型多了一个wchar_t,其实这个是由short和int定义而来,
typedef short int wchar_t;
所以 wchar_t 实际上的空间是和 short int 一样。一些基本类型可以使用一个或多个类型修饰符进行修饰:- signed
- unsigned
- short
- long
-
typedef 声明:您可以使用 typedef 为一个已有的类型取一个新的名字。下面是使用 typedef 定义一个新类型的语法:
typedef type newname;
,例如,下面的语句会告诉编译器,feet 是 int 的另一个名称:typedef int feet;
,现在,下面的声明是完全合法的,它创建了一个整型变量 distance:feet distance;
,定义了一个distance类型的变量
-
枚举类型:枚举类型(enumeration)是C++中的一种派生数据类型,它是由用户定义的若干枚举常量的集合。创建枚举,需要使用关键字 enum。枚举类型的一般形式为:
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
} 枚举变量;
例子如下:
如果枚举没有初始化, 即省掉"=整型常数"时, 则从第一个标识符开始。
例如,下面的代码定义了一个颜色枚举,变量 c 的类型为 color。最后,c 被赋值为 "blue"。
enum color { red, green, blue } c;
c = blue;
默认情况下,第一个名称的值为 0,第二个名称的值为 1,第三个名称的值为 2,以此类推。但是,您也可以给名称赋予一个特殊的值,只需要添加一个初始值即可。例如,在下面的枚举中,green 的值为 5。
enum color { red, green=5, blue };
enum clor {
red,green = 5,blue
}
- c++类型修饰符:多了一个wchar_t宽字类型,可以存储 Unicode 字符。
- c++中的引用,有点类似c语言的取地址符号,但是不同,就是定义一个新的引用变量来表示另一个变量,注意:在 C++ 中,通过使用引用参数,可以直接操作实参的值,而不是通过传递指针或值来进行操作。引用参数是对实参的别名,它们引用同一块内存空间!!!!!:
#include <iostream>
using namespace std;
int main ()
{
// 声明简单的变量
int i;
double d;
// 声明引用变量
int& r = i;
double& s = d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}
运行结果:
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7
c++标准的输入输出流:,c++的输入和是输出都是发生在流中的,输入输出流,字节流,感觉c++和c语言相比最大的变化就是1.输入输出变得简单,易于操作,2.能够面向对象编程。
I/O库头文件:
<<iostream>,顾名思义,该文件定义了 cin、cout、cerr 和 clog 对象,分别对应于标准输入流、标准输出流、非缓冲标准错误流和缓冲标准错误流。
<iomanip>,该文件通过所谓的参数化的流操纵器(比如 setw 和 setprecision),来声明对执行标准化 I/O 有用的服务。
<fstream>,该文件为用户控制的文件处理声明服务。我们将在文件和流的相关章节讨论它的细节。
标准的输出流(cout):预定义的对象 cout 是 iostream 类的一个实例。cout 对象"连接"到标准输出设备,通常是显示屏。cout 是与流插入运算符 << 结合使用的,如下所示:
#include<iostream>
using namespace std;
int main(){
char str[] = "Hello C++";
cout << "Value of str is:" << str <<endl;
}
当上面的代码被编译和执行时,它会产生下列结果:
Value of str is : Hello C++
C++ 编译器根据要输出变量的数据类型,选择合适的流插入运算符来显示值。<< 运算符被重载来输出内置类型(整型、浮点型、double 型、字符串和指针)的数据项。流插入运算符 << 在一个语句中可以多次使用,如上面实例中所示,endl 用于在行末添加一个换行符。
标准的输入流(cin):预定义的对象 cin 是 iostream 类的一个实例。cin 对象附属到标准输入设备,通常是键盘。cin 是与流提取运算符 >> 结合使用的,如下所示:
#include <iostream>
using namespace std;
int main( )
{
char name[50];
cout << "请输入您的名称: ";
cin >> name;
cout << "您的名称是: " << name << endl;
}
当上面的代码被编译和执行时,它会提示用户输入名称。当用户输入一个值,并按回车键,就会看到下列结果:
请输入您的名称: cplusplus
您的名称是: cplusplus
C++ 编译器根据要输入值的数据类型,选择合适的流提取运算符来提取值,并把它存储在给定的变量中。
流提取运算符 >> 在一个语句中可以多次使用,如果要求输入多个数据,可以使用如下语句:
cin >> name >> age;
这相当于下面两个语句:
cin >> name;
cin >> age;
标准错误流:cerr,预定义的对象 cerr 是 iostream 类的一个实例。cerr 对象附属到标准输出设备,通常也是显示屏,但是 cerr 对象是非缓冲的,且每个流插入到 cerr 都会立即输出。
cerr 也是与流插入运算符 << 结合使用的,如下所示:
#include <iostream>
using namespace std;
int main( )
{
char str[] = "Unable to read....";
cerr << "Error message : " << str << endl;
}
当上面的代码被编译和执行时,它会产生下列结果:
Error message : Unable to read....
标注日志流(clog):预定义的对象 clog 是 iostream 类的一个实例。clog 对象附属到标准输出设备,通常也是显示屏,但是 clog 对象是缓冲的。这意味着每个流插入到 clog 都会先存储在缓冲区,直到缓冲填满或者缓冲区刷新时才会输出。
clog 也是与流插入运算符 << 结合使用的,如下所示:
#include <iostream>
using namespace std;
int main( )
{
char str[] = "Unable to read....";
clog << "Error message : " << str << endl;
}
当上面的代码被编译和执行时,它会产生下列结果:
Error message : Unable to read....
注意:通过这些小实例,我们无法区分 cout、cerr 和 clog 的差异,但在编写和执行大型程序时,它们之间的差异就变得非常明显。所以良好的编程实践告诉我们,使用 cerr 流来显示错误消息,而其他的日志消息则使用 clog 流来输出。
-
c++数据结构:包括结构体,结构体指针,typedef关键字,这和c语言都是类似的,这里就不过多赘述。
-
c++类和对象:C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。
类用于指定对象的形式,是一种用户自定义的数据类型,它是一种封装了数据和函数的组合。类中的数据称为成员变量,函数称为成员函数。类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象。- c++ 类定义,定义一个类需要使用关键字 class,然后指定类的名称,并类的主体是包含在一对花括号中,主体包含类的成员变量和成员函数。
定义一个类,本质上是定义一个数据类型的蓝图,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。
以下实例我们使用关键字 class 定义 Box 数据类型,包含了三个成员变量 length、breadth 和 height:
- c++ 类定义,定义一个类需要使用关键字 class,然后指定类的名称,并类的主体是包含在一对花括号中,主体包含类的成员变量和成员函数。
class Box{
public:
double length //盒子的长度
double breadth //盒子的宽度
double height //盒子的高度
}
关键字 public 确定了类成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。您也可以指定类的成员为 private 或 protected,这个我们稍后会进行讲解。
- 定义c++对象,类提供了对象的蓝图,所以基本上,对象是根据类来创建的。声明类的对象,就像声明基本类型的变量一样。下面的语句声明了类 Box 的两个对象。
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
访问数据成员,类的对象的公共数据成员可以使用直接成员访问运算符 . 来访问。
- c++类继承,面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。
当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。继承代表了 is a 关系。例如,哺乳动物是动物,狗是哺乳动物,因此,狗是动物,等等。基本语法和例子如下:
// 基类
class Animal {
// eat() 函数
// sleep() 函数
};
//派生类
class Dog : public Animal {
// bark() 函数
};
一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名,形式如下:
class derived-class: access-specifier base-class
其中,访问修饰符 access-specifier 是 public、protected 或 private 其中的一个,base-class 是之前定义过的某个类的名称。如果未使用访问修饰符 access-specifier,则默认为 private。
一个类还可以继承多个类,基本语法如下:
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
<派生类类体>
};
- c++中的函数重载,和java中的构造函数类似,实例如下:
class printData
{
public:
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
};
- c++命名空间:假设这样一种情况,当一个班上有两个名叫 Zara 的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。
同样的情况也出现在 C++ 应用程序中。例如,您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。
因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。
我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。
定义命名空间,命名空间的定义使用关键字 namespace,后跟命名空间的名称,如下所示:
namespace namespace_name {
// 代码声明
}
name::code; // code 可以是变量或函数
using 指令:
您可以使用 using namespace 指令,这样在使用命名空间时就可以不用在前面加上命名空间的名称。这个指令会告诉编译器,后续的代码将使用指定的命名空间中的名称。,比如最基本的输入输出,cin = std::cin和cout = std::cout其实是使用std这个命名空间。因为cin和cout都是st命名空间中的对象!
# define 也是和c语言一样的作用,预定义!
- c++中的特殊的一些运算符:
- :: 作用域解析运算符或命名空间限定符,用于访问命名空间、全局变量或静态成员变量,其用法有很多,基本用法一般是
类/ /命名空间::类,函数,变量等等
- :: 作用域解析运算符或命名空间限定符,用于访问命名空间、全局变量或静态成员变量,其用法有很多,基本用法一般是
1)当存在具有相同名称的局部变量时,要访问全局变量:
// C++ program to show that we can access a global variable
// using scope resolution operator :: when there is a local
// variable with same name
#include<iostream>
using namespace std;
int x; // Global x
int main()
{
int x = 10; // Local x
cout << "Value of global x is " << ::x;
cout << "\nValue of local x is " << x;
return 0;
}
输出:
全局x的值为0
本地x的值为10
2)在类之外定义函数。
// C++ program to show that scope resolution operator :: is used
// to define a function outside a class
#include<iostream>
using namespace std;
class A
{
public:
// Only declaration
void fun();
};
// Definition outside class using ::
void A::fun()
{
cout << "fun() called";
}
int main()
{
A a;
a.fun();
return 0;
}
输出:
fun() called
3)访问一个类的静态变量。
// C++ program to show that :: can be used to access static
// members when there is a local variable with same name
#include<iostream>
using namespace std;
class Test
{
static int x;
public:
static int y;
// Local parameter 'a' hides class member
// 'a', but we can access it using ::
void func(int x)
{
// We can access class's static variable
// even if there is a local variable
cout << "Value of static x is " << Test::x;
cout << "\nValue of local x is " << x;
}
};
// In C++, static members must be explicitly defined
// like this
int Test::x = 1;
int Test::y = 2;
int main()
{
Test obj;
int x = 3 ;
obj.func(x);
cout << "\nTest::y = " << Test::y;
return 0;
}
输出:
静态x的值为1
本地x的值为3
测试:: y = 2
4)如果有多个继承:
如果两个祖先类中存在相同的变量名,则可以使用作用域运算符进行区分。
// Use of scope resolution operator in multiple inheritance.
#include<iostream>
using namespace std;
class A
{
protected:
int x;
public:
A() { x = 10; }
};
class B
{
protected:
int x;
public:
B() { x = 20; }
};
class C: public A, public B
{
public:
void fun()
{
cout << "A's x is " << A::x;
cout << "\nB's x is " << B::x;
}
};
int main()
{
C c;
c.fun();
return 0;
}
输出:
A的x是10
B的x是20
5)对于命名空间
如果两个命名空间中都存在一个具有相同名称的类,则可以将名称空间名称与作用域解析运算符一起使用,以引用该类而不会发生任何冲突
// Use of scope resolution operator for namespace.
#include<iostream>
int main(){
std::cout << "Hello" << std::endl;
}
在这里,cout和endl属于std命名空间。
6)在另一个类中引用一个类:
如果另一个类中存在一个类,我们可以使用嵌套类使用作用域运算符来引用嵌套的类
// Use of scope resolution class inside another class.
#include<iostream>
using namespace std;
class outside
{
public:
int x;
class inside
{
public:
int x;
static int y;
int foo();
};
};
int outside::inside::y = 5;
int main(){
outside A;
outside::inside B;
}
- c++中的特殊的一些运算符:
- :运算符,常用于子类继承父类,子类 : 父类,和构造函数中初始化成员变量。
1. 用于初始化成员变量
在类的构造函数中,可以使用 ":" 运算符来初始化成员变量。例如:
#include<iostream>
using namespace std;
class MyClass {
public:
int a,b,c; // 成员变量
MyClass(int x, int y, int z):a(x), b(y), c(z){} // 构造函数
};
int main() {
MyClass obj(1, 2, 3); // 创建对象并初始化成员变量
cout << "a: " << obj.a << endl;
cout << "b: " << obj.b << endl;
cout << "c: " << obj.c << endl;
return 0;
}
在上面的示例中,我们定义了一个名为MyClass的类,并声明了三个成员变量a、b和c。然后我们定义了一个构造函数,使用:运算符对成员变量进行初始化。在main函数中,我们创建了一个MyClass对象obj,并将参数1、2、3传递给构造函数,这样就完成了对成员变量的初始化。
需要注意的是,在使用:运算符初始化成员变量时,成员变量的顺序应该与类定义中声明的顺序相同。
2. 用于调用父类的构造函数
如果一个子类继承自一个父类,那么在定义子类的构造函数时,可以使用 ":" 运算符来调用父类的构造函数。例如:
#include <iostream>
using namespace std;
class Parent {
public:
Parent(int x) {
cout << "Parent constructor called with parameter " << x << endl;
}
};
class Child : public Parent {
public:
Child(int y) : Parent(y) {
cout << "Child constructor called with parameter " << y << endl;
}
};
int main() {
Child c(10);
return 0;
}
在这个示例中,我们定义了两个类:Parent和Child。Child是从Parent公开派生的。
在Child类的构造函数中,我们通过使用":"运算符来调用Parent类的构造函数,并将参数y传递给它。
在主函数中,我们创建了一个Child对象,并将值10传递给它。当Child对象被创建时,它会调用Child的构造函数,该构造函数又调用其父类Parent的构造函数。
将在控制台上输出
Child constructor called with parameter 10
Parent constructor called with parameter 10
3. 用于标识基类访问限定符
在派生类中,可以使用 ":" 运算符将基类的 public、protected 或 private 访问限定符进行分类。例如:
#include <iostream>
using namespace std;
class Base {
public:
int public_var;
protected:
int protected_var;
private:
int private_var;
};
class Derived : public Base {
public:
void setValues() {
public_var = 1; // 可以访问公有成员
protected_var = 2; // 可以访问保护成员
// private_var = 3; 不能访问私有成员
}
};
int main() {
Derived d;
d.setValues();
cout << "Public variable: " << d.public_var << endl;
// cout << "Protected variable: " << d.protected_var << endl; 不能访问
// cout << "Private variable: " << d.private_var << endl; 不能访问
return 0;
}
在这个例子中,定义了两个类:Base和Derived。Derived公开继承自Base。在Derived中,定义了一个setValues函数,它可以访问Base类的公有和保护成员。通过使用":"运算符,可以指定Derived从Base中继承的成员变量的访问权限。在这种情况下,将public_var声明为公有的,而将protected_var声明为受保护的。这意味着Derived和Base之间的关系现在是一个公开继承的关系,其中Derived可以访问Base的公有成员和受保护成员,但不能访问其私有成员。在main函数中,创建了Derived的一个实例,并调用setValues函数来设置public_var和protected_var的值。然后打印出public_var的值1:
Public variable: 1
总之,":" 运算符在 C++ 中有多种用途,其中最常见的是用于初始化成员变量和调用父类的构造函数。
- c++中的特殊的一些运算符:
- << 和 >>,在C++中,">>“和”<<"运算符是输入和输出运算符,分别用于从输入流中读取数据和向输出流中写入数据。
">>"运算符用于从输入流中读取数据,并将其存储到相应的变量中。例如,可以使用">>"运算符从标准输入流std::cin中读取一个整数并将其存储到变量x中:
int x;
std::cin >> x;
"<<"运算符用于向输出流中写入数据。例如,可以使用"<<"运算符将一个整数输出到标准输出流std::cout中:
int x = 42;
std::cout << "The value of x is: " << x << std::endl;
注意:<< 和 >>是可以重复多次使用的,endl只是一个换行的作用,可以使用'\n'代替,c++中没有javascript中的类似+号拼接字符串操作,而是直接把字符串看成一个输出流,用 << 隔开即可,例如:
#include <iostream>
//#include <string>
using namespace std;
int main()
{
char str[] = " hello";
char str2[] = "你好";
char name[10];
int age;
// 因为c++的char占一个字节,一个汉字两个字节所以要多分配一点空间,否则会产生截断
char sex[5];
char address[100];
cout << "直接输出:" << str;
cout << "换行输出1:" << str << endl;
cout << "换行输出2:" << str << '\n';
cout << "请分别输入:姓名,年龄,性别,地址:" << '\n';
cin >> name >> age >> sex >> address;
cout << name << "现在" << age << "岁,性别为:" << sex << ",家住在" << address;
/**
c++使用getline(input_stream, variable)来输入带有空格的字符串,input_stream是输入
方法名,比如cin,variable是要存储输入的字符串变量;
string类,头文件sting,关键字 string,可以定义字符串和字符串扮靓
**/
/**
getline()会读取上方第19行的cin的换行符也get到sname里面,解决方案:多了一个换行符,先读取或忽略就完事了。
1. cin.ignore() 默认跳过一个字符;2.cin.get()或getchar()读取换行符。
*
*/
cin。
cin.ignore();
cout << "请输入sname的值:" << endl;
string sname;
getline(cin, sname);
cout << "sname的值为:" << sname << "test";
return 0;
}
参考文章: