当前位置 : 主页 > 编程语言 > c语言 >

cpp基础认识(新手村)

来源:互联网 收集:自由互联 发布时间:2023-10-08
面向对象的四大特征 封装(Encapsulation):封装是将数据和方法组合在一起,对外部隐藏实现细节,只公开对外提供的接口。这样可以提高安全性、可靠性和灵活性。 继承(Inheritance)

面向对象的四大特征

  • 封装(Encapsulation):封装是将数据和方法组合在一起,对外部隐藏实现细节,只公开对外提供的接口。这样可以提高安全性、可靠性和灵活性。
  • 继承(Inheritance):继承是从已有类中派生出新类,新类具有已有类的属性和方法,并且可以扩展或修改这些属性和方法。这样可以提高代码的复用性和可扩展性。
  • 多态(Polymorphism):多态是指同一种操作作用于不同的对象,可以有不同的解释和实现。它可以通过接口或继承实现,可以提高代码的灵活性和可读性。
  • 抽象(Abstraction):抽象是从具体的实例中提取共同的特征,形成抽象类或接口,以便于代码的复用和扩展。抽象类和接口可以让程序员专注于高层次的设计和业务逻辑,而不必关注底层的实现细节。

标准库

  • 标准的 C++ 由三个重要部分组成:
  • 核心语言,提供了所有构件块,包括变量、数据类型和常量,等等。
  • C++ 标准库,提供了大量的函数,用于操作文件、字符串等。
  • 标准模板库(STL),提供了大量的方法,用于操作数据结构等。

命名空间

1.命名空间是为了解决多人合作取标识符时的重命名的问题

2.什么是命名空间

//命名空间
namespace A { // A是空间的名字
	int a;
	void func()
	{

	}
}

3.命名空间的注意

注意1:命名空间只能写在全局
注意2:命名空间可以嵌套命名空间
//命名空间可以嵌套命名空间
namespace Maker
{
	int a;
	namespace B
	{
		int b;
	}
}
注意3:命名空间是开放的,随之可以加入新成员,但是新成员你只能在加入后使用
namespace Maker
{
	int a;
	namespace B
	{
		int b;
	}
}

namespace Maker
{
	int c;
}(注:这两个Maker命名空间是表示的是同一个)
注意4:匿名命名空间 
//类似于static int d = 50
namespace
{
	int d = 50;
}
注意5:命名空间取别名
//命名空间取别名
void test01()
{
	namespace nameMaker = Maker;
	cout << nameMaker::a << endl;
}
注意6:分文件编写代码时,如果.h中有两个命名空间,但里面的成员函数或成员变量同名,在.cpp中实现函数时则需加上命名空间
test.h头文件
#pragma once
#include<iostream>

using namespace std;

namespace myMaker1
{
	void func();
}

namespace  myMaker2
{
	void func();
}
test.cpp文件
#include "test.h"

void myMaker1::func()
{
	cout << "func" << endl;
}

4.作用域运算符(::)

用来访问某个作用域里面的成员

namespace Maker
{
	int a;
	namespace B
	{
		int b = 40;
	}
}

namespace Maker
{
	int c = 30;//可以相当于限制在括号中的全局变量
}

int ma = 10;

int main()
{
	int ma = 20;
	//就近原则
	cout << "ma = " << ma << endl;
	cout << "::ma =" << ::ma << endl;
	cout << "Maker范围内 =  " << Maker::c << endl;
	cout << Maker::B::b << endl;
	return 0;
}

using声明和编译指令

using声明是让命名空间中某个标识符可以直接使用

namespace A
{
	int a = 10;
	int b = 20;
	int c = 30;
}

void test01()
{
	//usin声明是让命名空间中某个标识符可以直接使用
	using A::a;
	cout << a << endl;
}

using编译指令,让某个命名空间中的标识符都可以直接使用

void test02()
{
	//using编译指令,让某个命名空间中的标识符都可以直接使用
	using namespace A;
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;

	int a = 100;//类似于命名空间中的啊是全局变量,这里的a是局部变量
	cout << "a = " << a << endl;
}

注意:1.在一个程序中,变量只能定义一次,却可以声明多次。

2.定义分配存储空间,而声明不会。

结构体的加强

加强一:定义变量时不需要使用struct

//自定义数据类型
struct MyStruct
{
	char name[64];
	int age;
};

void test01()
{
	MyStruct a;//不需要加struct就可以定义变量
}

加强二:结构体内可以写函数

struct MyStruct1
{
	int a;
	void func()
	{
		cout << "func" << endl;
	}
};

void test02()
{
	MyStruct1 a1;
	a1.func();
}

更严格的类型转换

不能进行隐式转换,必须显示的转换


三目运算符

c语言的三目运算符返回的是右值

c++的三目运算符返回的是左值,是空间

左值和右值的概念

在c++中可以放在赋值操作符左边的是左值,可以放在赋值操作符右边的是右值

有些变量既可以当左值也可以当右值

左值为Lvalue,L表示Location,表示内存可以寻址,可以赋值

右值为Rvalue,R表示Read,就是可以知道它的值


const常量

const是一个限定符,它用来限定一个变量不允许改变,它将一个对象转换成一个常量

1.c语言的const修饰的变量都有空间

2.c语言的const修饰的全局变量具有外部链接属性

3.c++语言的const修饰的变量有时有空间,有时无空间(发生常量折叠,且未对变量进行取址操作)

const int aa = 10;//没有内存

void test()
{
	//发生了常量折叠
	cout << "aa = " << aa << endl;//在编译阶段, 编译器优化为:cout << "aa=" << 10 <<endl;

	const int bb = 20;//栈区
	//volatile禁止优化
	//volatile const int bb = 20;
	int* p = (int*)&bb;//进行了取址操作,所以有空间
	*p = 200;
	cout << "bb = " << bb << endl;//编译器优化了
	cout << "*p = " << *p << endl;

	cout << "a的地址:" << &bb << endl;
	cout << "p指向的地址:" << p << endl;
}

4.c++语言中的const修饰的全局变量具有内部链接属性

extern const int cc = 300;//加上extern就变为内部链接属性

5.c++编译器不能优化的情况

  • 自定义数据类型
  • 用变量给const修饰的局部变量赋值
  • 编译器是在编译阶段对数据进行优化

6.尽量用const代替define

  • define没有数据类型,const修饰的变量有数据类型,可以进行数据类型检查
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

#define MA 15
const short ma = 10;

void Myfun(short data)
{
	cout << "Myfun(short data)" << endl;
}

void Myfun(int data)
{
	cout << "Myfun(int data)" << endl;
}

int main()
{
	Myfun(MA);
	Myfun(ma);

	return 0;
}
  • const修饰的变量有作用域,define不重视作用域,不能限定常量的使用范围

引用(重点)

引用是c++对c 的重要扩充。在c/c++中指针的作用基本都是一样的,但是c++增加了另外一种给函数传递地址的途径,这就是按引用传递,它也存在于其他一些编程语言中,并不是c++的发明

  1. 引用的作用:与c语言的指针一样的功能,并且能是语法更加简洁
  2. 引用是什么:引用相当于给空间取别名
  3. 引用的语法
void func(int& a) // int &a = a;
{
	a = 200;
}


void test02()
{
	int a = 10;
	func(a);
	cout << "a = " << a << endl;
}
  1. 引用的注意
注意1:int& b = a; 这里的&不是取地址操作符,是引用的标记作用
注意2:引用创建时,必须初始化
注意3:引用一旦初始化就不能改变它的指向
注意4:引用必须引用一块合法的内存空间
  1. 数组的引用
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

int main()
{
	int arr[] = { 1,2,3,4,5 };
	//第一种方法
	//1.定义数组类型
	typedef int(MY_ARR)[5];
	//2.建立引用
	MY_ARR& p1 = arr;//建立引用,int &b =a;

	//第二种方法
	//直接定义引用
	int(&p2)[5] = arr; // int &b =a;

	//第三种方法
	typedef int(&MY_ARR1)[5];// 建立引用数组类型
	MY_ARR1 p3 = arr;

	for (int i = 0; i < 5; i++)
	{
		cout << p1[i] << ',';
		cout << p2[i] << ','; 
		cout << p3[i] << endl;
	}

	return 0;
}
  1. 引用的本质

引用的本质:C++中,引用的内部实现是一个指针常量。全部的指针操作由编译器自动转换。

(1)指针常量的指针指向不可变 → 引用初始化后不可更改

(2)指针常量指向的值可以改变 → 引用对应的数据可重新赋值

//发现是引用,转化为 int* const p = &a;
void testFunc(int& p){
		p =100;// p 是引用,转化为*p =100;
}

int main() {
	int a = 10;
	int& ref = a;	//编译器内部自动转换为 int * const ref = &a;这也说明引用为什么必须初始化

	ref = 20;		//编译器内部自动转换为 *ref = 20;
	cout << "a:" << a << endl;		
	cout << "ref:" << ref << endl;	

	//引用作为函数参数传递
	testFunc(a);		//编译器内部自动转换为 int * const ref = &a;
	cout << "a:" << a << endl;	
	cout << "ref:" << ref << endl;	

	return 0;
}

指针的引用(重点)

指针的引用是给指针变量这块空间取别名

void test()
{
	char a = 'm';
	char* p = &a;
	char*& p1 = p;
	/*int a = 1;
	int* p = &a;
	int*& p1 = p;*/

	cout << *p1 << endl;
}

//被调函数
void func(char* &tmp)
{
	char* tp;
	tp = (char*)malloc(64);
	memset(tp, 0, 64);
	strcpy(tp, "笑话");
	tmp = tp;
}
//主调函数
void test1()
{
	char* mp = NULL;
	func(mp);
	cout << mp << endl;
}

c和c++的区别

  1. c语言的结构体不能写函数,c++可以
  2. 结构体定义变量时,c++不需要加struct关键字
  3. 更加严格的类型检查
  4. const修饰的变量,c++有事没有内存,c语言的都有内存
  5. 三目运算符返回的值不一样
  6. 引用和c语言的指针功能一样
上一篇:数据结构的思维导图(帮助梳理脉络)
下一篇:没有了
网友评论