C++特点及优势
(1)实现了面向对象,在高级语言中,处理运行速度是最快;
(2)非常灵活,功能非常强大,相对于C的指针优势,C++的优势为性能和类层次结构;
(3)严谨、精确和数理化........
C++和C语言的区别
C语言是面向过程的语言,C++是面向对象的语言。
C++兼容C语言的头文件 #include <cstdio>
标准输入输出
输出流对象(std::cout<<)
可以自动识别基本类型的输出类型
编译:g++ demo.cpp
输入流对象(std::cin>>)
自动识别基本类型的数据类型
练习:输入一个字符 如果是大写 则转为小写 如果是小写则转为大写
#include <iostream>
int main()
{
char c;
std::cin >> c;
if (c >= 'a' && c <= 'z')
{
//a = a - 32;
std::cout << (char)(c - 32) << std::endl;
}
else if(c >= 'A' && c <= 'Z')
{
c += 32;
std::cout << c << std::endl;
}
return 0;
}
cin同时获取多个值
#include <iostream>
int main(int argc, char const *argv[])
{
int a;
char c;
std::cin >> a >> c;
std::cout << a << " " << c << std::endl;
return 0;
}
命名空间
避免命名空间污染,C++的标准库都是在std命名空间中定义的(所有的类和对象)。
表示方法
方式一:using namespace std;
方式二:std::cout
自定义命名空间
#include <iostream>
using namespace std;
namespace teacher
{
char name[20] = "zhangsan";
void showName()
{
cout << name << endl;
}
}
namespace worker
{
char name[20] = "lisi";
void showName()
{
cout << name << endl;
}
}
using namespace teacher;
using namespace worker;
int main(int argc, char const *argv[])
{
//cout << name << endl; //报错的位置
cout << teacher::name << endl;
cout << worker::name << endl;
cout << "-----------" << endl;
teacher::showName();
worker::showName();
return 0;
}
teacher和worker命名空间中都有name,如果不写命名空间,会出现访问不明确的错误。
C++增加bool类型
(1)bool是基本数据用来表示逻辑真假
(2)非0为真 true,0为假 false
(3)增强程序可读性 int isFull(); bool isFull();
字符串处理
(1)延续C风格,字符数组 char s[20] = "hello"; 字符指针 char *s = "hello";
(2)C++标准库中string类(string不是基本数据类型,而是类类型,对象类型)
创建string对象
#include <iostream> // iostream头文件中包含string头文件,所以可以省略
//#include <string>
using namespace std;
int main()
{
string s1 = "hello world";
string s2("hello s2");
string s3(s2); // s3是用s2复制的string类型对象
string s4 = s1; //string对象复制可以通过赋值符号=,直接将值赋予目标对象
cout << "s1:" << s1 << endl;
cout << "s2:" << s2 << endl;
cout << "s3:" << s3 << endl;
cout << "s4:" << s4 << endl;
return 0;
}
字符串拼接和比较
string只能拼接string,拼接其他类型需要使用sprintf()进行复杂的字符串格式化
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1 = "hello";
string s2 = "world";
s1 += s2;//把s2的字符串追加到s1后面
cout<<s1<<endl;
//s1 += 1;//错误 string类型的拼接,只能拼接string类型或者C风格字符串
char buf[100];
sprintf(buf,"%s%d",s1.c_str(),1);//c_str():string类型或者C风格字符串
cout<<buf<<endl;
//字符串比较
cout<<(s1 == s2)<<endl; // 比较的是第一个不相等的ASCII码值
cout<<(s1 != s2)<<endl;
return 0;
}
empty和size函数
empty()判断空,如果字符转为空,返回true;否则,返回false
size()返回字符串长度,和strlen()相同
#include <iostream>
using namespace std;
int main()
{
string s1 = " ";
cout << s1.empty() << endl;
string s2 = "";
cout << s2.empty() << endl;
string s3 = "hello world";
cout << s3.size() << endl;
return 0;
}
cin和getline函数输入字符串
cin遇到空格结束
getline函数,输入字符串遇到'\n'结束输入(C++中无法使用gets函数,所以用此函数)
#include <iostream>
using namespace std;
int main()
{
string s1;
cout << "please input s1" << endl;
// 参数1:cin输入流获取字符串,参数2:读取到的字符串存放为止
getline(cin,s1);
cout << "getine s1:" << s1 << endl;
string s2;
cout << "please input s2" << endl;
cin >> s2;
cout << "cin s2:" << s2 << endl;
return 0;
}
引用
引用的本质就是给变量起别名。
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int& b = a;
return 0;
}
特点(重点)
(1)必须进行初始化
(2)引用不能单独存在,也不能改变指向
(3)普通引用不能用常量或者临时值进行初始化
引用作为形参类型
交换a,b的值
#include <iostream>
using namespace std;
void swap(int& x,int& y)
{
int temp;
temp = x;
x = y;
y = temp;
}
int main()
{
int a = 10,b = 20;
swap(a,b);
cout << a << " " << b << endl;
return 0;
}
引用作为返回值
引用作为返回值,是返回变量本身,而不是一个临时的值,要保证变量的生命周期足够长。
const修饰的引用(常引用)
指针的引用和数组的引用
引用和指针的区别(重点)
(1)不存在空的引用,引用必须连接到一块合法的内存;指针可以是空指针。
(2)引用被初始化为一个对象,就不能被指向到另一个对象;
指针可以在任何时候指向到另一个对象。
(3)引用必须在创建时被初始化;指针可以在任何时间被赋值。
动态内存分配
(1)堆区:自定义生命周期(只申请不释放堆区内存,会内存泄漏)
(2)栈区:作用域结束,变量才释放
(3)静态变量:程序结束才释放
动态内存的申请和释放
new和delete
C++中new关键字(运算符)申请的内存空间是有类型的给内存初始化,返回指定类型的指针,并且可以自动计算所需大小。
申请变量
#include <iostream>
using namespace std;
int main()
{
int* p = new int; // 指针变量p指向,在堆区申请一个int类型的内存
*p = 10;
delete p; // 释放new在堆区申请int类型空间
p = NULL;
return 0;
}
申请数组
#include <iostream>
using namespace std;
int main()
{
int* p = new int[10]; // 在堆区申请一个int类型的10个元素的数组
delete[] p; // 释放数组
p = NULL;
return 0;
}
释放指针置空
delete释放的是指针指向的内存,指针是一个变量,只有在程序结束时才被销毁。释放了内存空间后,原来指向这块空间的指针还是存在,只不过现在指针指向的内容垃圾区域,所以释放内存后把指针指向NULL,防止指针在后面不小心又被解引用。
new和malloc的区别(重点)
(1)malloc是库函数;new是关键字(运算符)
(2)malloc申请的空间没有类型(void *),需要强转;new申请的直接初始化
(3)new会调用构造函数
函数延伸
重载
英文叫做overload,C++中允许创建多个名称相同的函数,需要满足:
(1)在同一作用域内,函数名相同,形参列表不同(类型或者个数不同),返回值不作为决定性条件;
(2)如果参数列表相同,但返回值不同是不可以重载的。
函数默认参数
正常来说函数调用时,形参从实参获取值,但是还可以给形参一个默认值,这样形参就不必从实参取值了(一旦某个形参被赋予了默认值,那么其后面的所有形参都必须有默认值)。
当函数的声明和定义分开写时,只能在声明的部分写默认参数
#include <iostream>
using namespace std;
void fun(int a = 10, int b = 20, int c = 30);
int main()
{
fun();
fun(1);
return 0;
}
void fun(int a, int b, int c)
{
cout << a << b << c <<endl;
}
类的初识
栈区创建对象
#include <iostream>
using namespace std;
class Student
{
public:
string name;
int age;
void set(string n, int a)
{
name = n;
age = a;
}
};
int main(int argc, char *argv[])
{
Student s; //栈区实例化对象
//直接对成员变量赋值
s.name = "zhangsan";
s.age = 18;
//调用成员函数间接赋值
s.set("lisi",20);
return 0;
}
堆区创建对象
int main(int argc, char *argv[])
{
Student *s = new Student() ; //在堆区创建一个Student类型对象
//直接对成员变量赋值
s->name = "zhangsan";
s->age = 18;
//调用成员函数间接赋值
s->set("lisi",20);
delete s;
s = NULL;
return 0;
}