C++基础

优先级: 2 学习权重: 9 学习目标: 了解基础语法,为后面WindowsApi及QT等c++面向对象项目提供基础 学习类型: 编程/语法学习 学习进度: 0.1 状态: 进行中 语言类别: C++

HelloWorld

/images/JavaBase/Untitled.png

#include <iostream>
#define day 7;  //常量

using  namespace std;

const int b = 20; //常量

int main() {
	int a = 10;
	string b = "world";
	cout << "hello" << b << a << endl;
	system("pause");
	return 0;
}

命名规则

字母数字下划线,大小写敏感

整型

short短整型 2的15次方-1 -32768~32767

int 整型 2的31次方-1

long 长整型

long long 长长整型

越界会变成负数

sizeof 关键字

cout << sizeof(a) << endl;  //查看数据类型占用的空间
cout << sizeof(int) << endl; //可以是变量类型,也可以是变量名

实型(浮点型)

float 7位有效数字

double 15-16为有效数字

小数点后及之前的都算有效数字

字符型

char 单字符,占用1个字节

字符赋值用单引号赋值。

强制类型转换,转换成ascii码

char c = 'a';
cout << (int)c << endl;

字符串类型

//#include <string> //引用时尽量声明头文件
string b = "world"; //cpp风格的字符串
char b1[] = "world"; //c语言风格的字符串,字符数组
cout << "hello" << b << a << endl;
cout << "hello" << b1 << a << endl;

数据输入

string newinput; //使用前声明输入类型
cin >> newinput; // cin输入
cout << newinput << endl;

三目运算符

int d = 10;
int e = 29;
int f = d > e ? d : e; 
cout << f << endl;  //29
d > e ? d : e = 100;
cout << e << endl; //100

switch分支

switch (f) {
	case 28: 
		cout << f << endl;
		break;
	default:
		cout << "error" << endl;
		break;
	}

goto

FLAG:
goto FLAG;

数组sizeof

#include <iostream>

using  namespace std;

int main() {
	int arr[5] = { 1,2,3,4,5 };
	cout << "数组内存空间" << sizeof(arr) << endl;
	cout << "数组首地址空间" << sizeof(arr[0]) << endl;
	cout << "数组长度" << sizeof(arr)/sizeof(arr[0]) << endl;
	cout << "数组首地址十六进制" << arr << endl;
	cout << "数组首地址强转十进制" << (int)arr << endl;
	cout << "数组第一个元素地址,&为取地址符号" << &arr[0] << endl;
	cout << "数组第二个元素地址,&为取地址符号" << &arr[1] << endl;

	system("pause");
	return 0;
}

二维数组

函数

#include <iostream>

using  namespace std;

int sumadd(int a, int b) {
	return a + b;
}

int main() {
	int a = sumadd(5, 6);
	cout << sumadd(5, 6) << endl;

	system("pause");
	return 0;
}

定义函数卸载main函数前不用声明定义

值传递

函数声明

提前声明函数

#include <iostream>

using  namespace std;

int sumadd(int a, int b) ;
//函数声明,需要函数返回值,函数名,参数列表
//声明可以写多次

int main() {
	cout << sumadd(5, 6) << endl;

	system("pause");
	return 0;
}

//定义只能写一次
int sumadd(int a, int b) {
	return a + b;
}

函数的分文件编写

头文件(声明函数)==函数中使用的cout方法需要在头文件中调用

#include <iostream>
using  namespace std;
int sumadd(int a, int b);
int sumadd(int a, int b, int c);

函数源文件

#include "maths.h"
int sumadd(int a, int b) {
	cout << a+b << endl;
	return a + b;
}

int sumadd(int a, int b, int c) {
	cout << a + b +c << endl;
	return a + b + c;
}

调用过程源文件===调用文件和函数源文件同时包含头文件

#include <iostream>
#include "maths.h"

using  namespace std;

int main() {
	cout << sumadd(5, 6,7) << endl;
	system("pause");
	return 0;
}

指针

#include <iostream>
#include "maths.h"

using  namespace std;

int main() {
	int a = 10;
	int* p; //p为指针类型,声明p的int类型指针
	p = &a; //&号取地址
	cout << p << endl; //p 直接打印为地址编号
	cout << *p << endl; //*号取值,c中叫解引用
	*p = 100;
	cout << a << endl; //通过指针修改指针指向的内存数据
	cout << a << endl;

	cout << sizeof(p) << endl; //32系统占用4字节,64位占8个字节

	
	cout << &p << endl; //p指向a的地址,&p为p指针的内存地址

	system("pause");
	return 0;
}

空指针和野指针

空指针常用在初始化指针变量,该指针所指向内存不可访问

#include <iostream>
#include "maths.h"

using  namespace std;

int main() {
	int* p=NULL; //空指针

	//以下代码不允许访问
	cout << *p << endl;

	system("pause");
	return 0;
}

野指针,指向非法数据空间,范围跟会因权限报错

#include <iostream>
#include "maths.h"

using  namespace std;

int main() {
	int* p=(int *)0x1100; //野指针

	//以下代码不允许访问
	cout << *p << endl;

	system("pause");
	return 0;
}

const指针

const 修饰指针 常量指针 const int * p = &a; //此时const相当于修饰&a

指针的指向可以修改(p = &b; ),指针指向的值不可修改(*a =199;//错误)

const 修饰常量 指针常量 int * const p =&a;

指针的指向不可以修改,指针指向的值可以修改

const 既修饰指针又修饰常量 const int * const p =&a;

指针的指向和指向的值都不可修改

指针和数组

include <iostream>
#include "maths.h"

using  namespace std;

int main() {
	int arr[4] = { 1,2,3,4 };
	int* p1 = &arr[0];
	*p1 = 0;
	cout << arr[0] << endl;

	int * p2 = arr;//arr本身就是内存地址,无需使用&
	cout << *p2 << endl;
	p2++; //直接将指针偏移4个字节
	cout << *p2 << endl;

	system("pause");
	return 0;
}

利用指针遍历数组

#include <iostream>
#include "maths.h"

using  namespace std;

int main() {
	int arr[] = { 1,2,3,4,12,22,333,4,21,24 };
	int* p1 = &arr[0];
	*p1 = 0;
	//cout << arr[0] << endl;

	int * p2 = arr;//arr本身就是内存地址,无需使用&
	for (int i = 0; i <= sizeof(arr) / sizeof(arr[0])-1; i++)
	{
		cout << *p2 << endl; //循环遍历
		p2++; //直接将指针偏移4个字节
		//简写成 cout << *p2++ << endl;

	}

	system("pause");
	return 0;
}

指针和函数

指针作为参数可以改变值

#include <iostream>
#include "maths.h"

using  namespace std;
void swap(int a, int b);
void swap(int* pa, int* pb); //方法重写需要多次声明
int main() {
	int a = 10;
	int* pa = &a;
	int b = 102;
	int* pb = &b;

	swap(pa,pb);
	cout << a<< b<<endl;

	system("pause");
	return 0;
}

void swap(int a, int b) {
	int tmp = a;
	a = b;
	b = tmp;
	cout << "swap" << a << b << endl;
}

void swap(int * pa, int * pb) {
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
	cout << "swap" << *pa << *pb << endl;
}

结构体+数组遍历

#include <iostream>
#include <string>
//#include "maths.h"

using  namespace std;

struct Student
{
	string Name;
	int age;
	int score;
};

string to_string(Student s);

int main() {
	Student class1[] = {
		{"a",1,2},
		{"b",11,22},
		{"c",111,222}
	};

	for (int i = 0; i <= sizeof(class1)/sizeof(class1[0])-1; i++)
	{
		cout << to_string(class1[i]) << endl;
	}

	system("pause");
	return 0;
}

string to_string(Student s) {
	string str = "姓名:" + s.Name + "年龄:" + to_string(s.age) + "分数:"+  to_string(s.score);
	return str;
}

结构体指针+函数传参

传入结构体指针传参,指针占用4字节/8字节,作为参数传递省内存

加上const 可以防止方法中误操作数据

#include <iostream>
#include <string>
//#include "maths.h"

using  namespace std;

struct Student
{
	string Name;
	int age;
	int score;
};

string to_string(const Student *s);

int main() {
	Student class1[] = {
		{"a",1,2},
		{"b",11,22},
		{"c",111,222}
	};

	for (int i = 0; i <= sizeof(class1)/sizeof(class1[0])-1; i++)
	{
		cout << to_string(&class1[i]) << endl;
	}

	system("pause");
	return 0;
}

string to_string(const Student *s) {
	string str = "姓名:" + s->Name + "年龄:" + to_string(s->age) + "分数:"+  to_string(s->score);
	return str;
}

内存堆创建释放

new/delete

#include <iostream>
#include <string>
//#include "maths.h"

using  namespace std;

struct Student
{
	string Name;
	int age;
	int score;
};

string to_string(const Student* s);

int main() {
	Student* s = new Student({ "aaa",12,12 });//new创建的是指针,需要使用指针接收
	cout << to_string(s) << endl;
	delete s; //使用delete关键字释放内存

	int* arr = new int[10];
	delete[] arr; //new 数组指针 需要使用delete[]释放

	Student* sarr[] ={
		new Student {"a",1,2},
		new Student{"b",11,22},
		new Student{"c",111,222}
	};
	//sarr数组指针,存储Student指针,释放需要使用for循环遍历释放
	cout << sarr[0]->Name << endl;

	Student* sarr1 = new Student[]{
		{"a",1,2},
		{"b",11,22},
		{"c",111,222}
	};

	delete[] sarr1; //new 结构体数组返回指针,需要使用delete[]释放

	system("pause");
	return 0;
}

string to_string(const Student* s) {
	string str = "姓名:" + s->Name + "年龄:" + to_string(s->age) + "分数:" + to_string(s->score);
	return str;
}

C++引用

变量的别名

引用在初始化创建之后不可被更改

#include <iostream>
#include <string>
//#include "maths.h"

using  namespace std;

struct Student
{
	string Name;
	int age;
	int score;
};

string to_string(const Student* s);

int main() {
	Student* s = new Student({ "aaa",12,12 });//new创建的是指针,需要使用指针接收

	// 引用时一种指针常量
	//数据类型 &别名 = 原名;
	Student* &s1 = s; //s为指针,所以别名需要创建指针类型,s1和s指向同一内存

	cout << to_string(s) << endl;
	cout << to_string(s1) << endl;
	
	delete s1;
	//delete s; //使用delete关键字释放内存
	system("pause");
	return 0;
}

string to_string(const Student* s) {
	string str = "姓名:" + s->Name + "年龄:" + to_string(s->age) + "分数:" + to_string(s->score);
	return str;
}

引用作为函数参数

#include <iostream>
#include "maths.h"

using  namespace std;
void swap(int a, int b); //值传递不会修改数据
void swap1(int &a, int &b); //引用传递
void swap(int* pa, int* pb); //指针地址传递
int main() {
	int a = 10;
	int b = 102;

	swap(&a, &b);
	cout << a << b << endl;

	int c = 101;
	int d = 103;

	swap1(c, d);
	cout << c << d << endl;

	system("pause");
	return 0;
}

//值传递
void swap(int a, int b) {
	int tmp = a;
	a = b;
	b = tmp;
	cout << "swap zhi" << a << b << endl;
}

//地址传递
void swap(int *pa, int *pb) {
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
	cout << "swap address" << *pa << *pb << endl;
}

//引用传递
void swap1(int &a, int &b) {
	int tmp = a;
	a = b;
	b = tmp;
	cout << "swap yinyong" << a << b << endl;
}

引用作为返回值

不要返回局部变量的引用

错误示范

#include <iostream>
#include "maths.h"

using  namespace std;

int& getint();
int main() {

	int& b = getint(); //此处局部变量a调用完即被释放

	cout << b << endl; //第一次打印数据被编辑器保留
	cout << b << endl; //第二次已被释放,输出乱码

	system("pause");
	return 0;
}

int& getint() {
	int a = 10;
	return a;
}

正确用法

#include <iostream>
#include "maths.h"

using  namespace std;

int& getint();
int main() {

	int &b = getint();

	cout << b << endl;

	getint() = 100; //此处函数作为左值,相当于将a/&b赋值为100

	cout << b << endl;

	system("pause");
	return 0;
}

int& getint() {
	static int a = 10;//此处将局部变量设置为系统变量,程序结束时由系统释放
	return a;
}

引用的本质

#include <iostream>
#include "maths.h"

using  namespace std;

int main() {
	int a = 19;

	int &n = a;
	// 引用相当于创建了指针常量
	int* const n1 = &a;

	n = 20;
	// 引用赋值相当于自动指针解引用
	*n1 = 20;
	

	system("pause");
	return 0;
}

函数默认参数

#include <iostream>
#include "maths.h"

using  namespace std;

int test(int a, int b = 29, int c = 290) {
	return a + b + c;
}
//声明中有默认参数,实现中则不允许有默认参数,声明和实现只能存在一处默认值
int test2(int a, int b = 29, int c = 290);
int test2(int a, int b, int c) {
	return a + b + c;
}

//占位参数之只声明类
int test3(int a, int b, int) {
	return a + b;
}

int main() {

	cout << test(11) << endl;

	system("pause");
	return 0;
}

c++ 方法重载

#include <iostream>

using  namespace std;

int sumadd(int a, int b) ;
int sumadd(int a, int b,int c);

int main() {
	cout << sumadd(5, 6,7) << endl;

	system("pause");
	return 0;
}

int sumadd(int a, int b) {
	return a + b;
}

int sumadd(int a, int b,int c) {
	return a + b +c;
}

c++引用作为重载条件

#include <iostream>
#include "maths.h"

using  namespace std;
void swap(int a, int b); //值传递不会修改数据
void swap1(int &a, int &b); //引用传递
void swap1(const int& a, const int& b);
void swap(int* pa, int* pb); //指针地址传递
int main() {
	int a = 10;
	int b = 102;

	swap(&a, &b);
	cout << a << b << endl;

	int c = 101;
	int d = 103;

	swap1(c, d);
	cout << c << d << endl;
	swap1(10, 20);

	system("pause");
	return 0;
}

//值传递
void swap(int a, int b) {
	int tmp = a;
	a = b;
	b = tmp;
	cout << "swap zhi" << a << b << endl;
}

//地址传递
void swap(int* pa, int* pb) {
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
	cout << "swap address" << *pa << *pb << endl;
}

//引用传递
void swap1(int &a, int &b) {
	int tmp = a;
	a = b;
	b = tmp;
	cout << "swap yinyong" << a << b << endl;
}

//引用传递
void swap1(const int &a, const int &b) {
	cout << "swap yinyong" << a << b << endl;
}

类和对象

封装-继承-多态

#include <iostream>
#include "maths.h"

using  namespace std;

class Circle {
public:
	const double Pi = 3.14;
	
	double mianji;
	double clacZC() {
		return 2 * Pi * m;
	}
	void setName(string _name) {
		name = _name;
	}
	string getName() {
		return name;
	}

	void setM(int _m) {
		m = _m;
		mianji = 2 * Pi * m;
	}

	int getM() {
		return m;
	}
	Circle() {  //构造函数
		mianji = 2 * Pi * m;
	}

private:
	string name;
	int m = 0;
};

int main() {
	Circle c1;
	c1.setM(2);
	cout << c1.clacZC() << endl;

	Circle c2;
	cout << c2.mianji<< endl;

	system("pause");
	return 0;
}

权限:

public 公共 类内访问 类外访问

protected 保护 类内访问 类外拒绝访问———子类可访问

private 私有 类内访问 类外拒绝访问———子类不允许访问

struct和class

struct 默认权限为公共

class 默认为私有

构造函数

可以重载

拷贝构造函数

创建对象时直接拷贝一个已经存在的对象

Person(const Person &p){
	age = p.age;
}

析构函数

~类名(){}

析构函数在栈区运行

函数执行完会运行析构函数

推测用于调用资源的释放

comments powered by Disqus