C++基础

文章目录

    • 1.C和C++衔接
    • 2.定义命名空间
    • 3.C++输入,输出
    • 4.缺省参数
  • 5.函数重载
  • 6.引用
    • 6.1引用概念
    • 6.2引用要求

1.C和C++衔接

C++兼容C语言
命名空间:namespace
标准库的东西都放到std。
using namespace std;
展开命名空间。
意义:补C语言的坑,弥补不足。没有解决命名重复的问题
命名冲突问题
C++基础_第1张图片
C++基础_第2张图片
C++基础_第3张图片
命名空间namespace后面定义一个名字,名字是一个域,可以把其保护起来
namespace ljq

#include 
#include 

namespace ljq
{
	int rand = 0;
	
}
int main()
{
	printf("%d", rand);
	return 0;
}

using namespace ljq;//全局域里找

C++基础_第4张图片
//打印的是函数名,是地址,作为函数名走的
C语言同一个域不能定义同一个变量,不同的域可以定义

int a=0;//全局域
int main()
{
int a=1;
printf("%d",a);//就近原则,局部优先
printf("%d", ::a);//::域作用限定符,指定去左边的域找。空白表示全局域
return 0;//输出1
}

C++基础_第5张图片

  1. 在项目中,尽量不要用using namespace std;,可能冲突
  2. 平常练习用using namespace std;
  3. 项目中可以指定命名空间访问展开常用
//用库的std命名空间
#include 
int main()
{
	std::cout << "hello world" <<std:: endl;//std:进行指定访问
		return 0;
}

C++基础_第6张图片
进行指定访问

#include
using std::cout;//把std中的cout和endl放到全局里
using std::endl;
int main()
{
std::vector<int> v;//指定
v.push_back(1);//push_back:进行尾插数据
cout<<"hello world"<<endl;
return 0;
}

2.定义命名空间

可以定义变量,函数,类型

int a;

int Add(int left,int right)
{
return left+right;
}

嵌套

namespace N2
{
 int a;
 int b;
 int Add(int left,int right)
 {
 return left+right;
 }
 namespace N3
 {
  int c;
  int d;
  int Sub(int left,int right)
  {
  return left-right;
  }
 }
}
  

同一工程中允许存在多个名称相同的命名空间,编译器最后会合成同一个命名空间中

namespace N1
{
int Mul(int left,int right)
{
return left*right;
}
}

3.C++输入,输出

C++可以自动识别类型
IO流

#include 
#include
using namespace std;
int main()
{
	int i;
	double d;
	cin >> i >> d;
	cout << i << endl;
	cout << d << endl;
	return 0;
}

endl:\n
cin:istream类型对象
cout:ostream类型对象
特点:自动识别类型

.>>:流提取
<<:流插入

控制台应用程序
C++基础_第7张图片
P.S.可以继续使用C语言

4.缺省参数

缺省参数:声明参数时可以给形参缺省值。
觉得C语言不好用,C加加补的。

#include 
#include
using namespace std;

void Func(int a)//形参
{
	cout << a << endl;
}

int main()
{
	
	Func(1);
	Func(2); 
	Func(3);//传一个实参给形参

	return 0;
}

C++基础_第8张图片
void Func(int a=0)
//缺省参数,备胎
//传了参数没关系,没传写缺省值0去传参

  • 全缺省
    多个参数全部缺省,调用函数非常灵活。也可以传一部分。从左向右给。
#include 
#include
using namespace std;

void Func(int a = 10,int b = 20,int c=30)
{
	cout << "a= " <<a<< endl;
	cout << "b= " << b << endl;
	cout << "c= " << c << endl<<endl;

}

int main()
{
	
	Func(1,2,3);
	Func(2); 
	Func();

	return 0;
}

C++基础_第9张图片

  • 半缺省
    void Func(int a ,int b = 20,int c=30)
    给了两个缺省值,缺省必须从右向左连续缺省,不能间隔。
    缺省在栈的定义中有用。
    一定是从左向右传,
    不可以Func(,,1)。
struct Stack
{
int* _a;
int _top;//前面的_为了更好的区分
int _capacity;//之前全部初始化为空不好
//1.扩容有代价
//2.初始化为0时扩容扩2倍仍为0
};
void StackInit(struct Stack* ps,int capacity=4)//半缺省
{
ps->_a=()malloc(sizeof(int)*capacity);//capacity:默认第一次要开的空间
//。。。检查
ps->_top=0;
ps->_capacity=capacity;
}
int main()
{
struct Stack st1;
StackInit(&st1,100);//知道一定会插100个,就会传参数100
//提前开好空间,插入数据避免扩容
}

缺省参数不能在函数声明和定义的位置同时出现
分离定义时,以声明为准,声明说的算。

5.函数重载

也是觉得C语言不好用,C加加补的。
函数重载一词多义应该可以区分
函数的一种特殊情况。C++允许在同一作用域中声明几个功能相类似同名函数。这些同名函数的形参列表参数个数类型顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
参数类型不同:

int Add(int left, int right)
{
	return left + right;

}
double Add(double left, double right)
{
	return left + right;

}
int main()
{
	cout << Add(1, 2) << endl;
	cout << Add(1.1, 2.2) << endl;
	return 0;
}

C++基础_第10张图片

double Add(double left, double right)
{
	return left + right;

}
int Add(double left, double right)
{
	return left + right;

}返回值不同不构成重载。调用时无法区分。只有参数不同才构成
int main()
{
	cout << Add(1, 2) << endl;
	cout << Add(1.1, 2.2) << endl;
	return 0;
}

函数重载真正的意义:让用的地方很方便,就像用同一个函数一样

  • 为什么C++支持函数重载,C语言不支持。C++如何支持的呢?

6.引用

6.1引用概念

给已有的变量取别名。
C++基础_第11张图片

int main()
{
	int a = 0;
	int& b = a;//引用,共用同一空间
	cout << &a << endl;
	cout << &b << endl;//取地址
	return 0;
}

C++基础_第12张图片
引用类型必须和引用实体同种类型

6.2引用要求

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个是实体,不能再引用其他实体。
int main()
{
int a = 0;
int& b = a;
int x=20;
//
b=x;//b是x的别名?还是x赋值给b?是赋值
}

引用使用场景:
1.做参数
a.一般做输出型参数

void Swap(int& r1, int& r2)//引用,r1是a的别名,r2是b的别名
{
	int tmp = r1;
	r1 = r2;
	r2 = tmp;

}
int main()
{
	int a = 0, b = 2;
	Swap(a, b);
	return 0;
}

b.大对象传参,提高效率
引用不开空间
2.引用可做返回值
a.输出型返回对象,调用者可以修改返回对象

int& Count()//传值返回
{
	static int n = 0;
	n++;
	//...
	return n;//用n的拷贝做表达式的返回值
}
int main()
{
	int ret = Count();
	return 0;
}

C++基础_第13张图片

C++基础_第14张图片
传引用返回
不产生拷贝
int& Count()//返回n的别名
引用返回的语法:返回返回对象的别名
C++基础_第15张图片
前提:
出了函数作用,返回对象就销毁了。那么一定不能引用返回,一定要用传值返回
什么时候可以用引用返回?
出了作用域n还在,可以引用返回
下面的场景可以用

int& Count(){
	static int n = 0;
	n++;
	//...
	return n;
}

使用引用返回
减少拷贝,提高效率

//Stack.h
#pragma once
#include
#include
using namespace std;
void StackInit(struct Stack* ps, int capacity = 4);//声明
//引用返回的场景
typedef struct SeqList
{
	int* a;
	int size;
	int capacity;
}SL;
void SLInit(SL& s, int capacity = 4);

void SLPushBack(SL& s, int x);
//顺序表支持一个修改顺序数据的函数
//void SLModity(SL& s, int pos, int x);
int& SLAt(SL& s, int pos);
//Stack.cpp
#include "Stack.h"
void StackInit(struct Stack* ps, int capacity)
{
	ps->a = (int*)malloc(sizeof(int) * capacity);
	ps->top = 0;
	ps->capacity = capacity;
}
void SLInit(SL& s, int capacity )
{
	s.a = (int*)malloc(sizeof(int) * capacity);
	assert(s.a);
	s.size = 0;
	s.capacity = capacity;
}
void SLPushBack(SL& s, int x)
{
	if (s.size == s.capacity)
	{
		//
	}
	s.a[s.size++] = x;
}
int& SLAt(SL& s, int pos)//引用返回,可随意修改
{
	assert(pos >= 0 && pos <= s.size);
		return s.a[pos];//关注这个对象,只要在堆上,出了作用域还在可以用引用返回。和其他无关

}
//Test.cpp
#include "Stack.h"
int main()
{
	SL sl;
	SLInit(sl);
	SLPushBack(sl, 1);
	SLPushBack(sl, 2);
	SLPushBack(sl, 3);
	SLPushBack(sl, 4);
	for (int i = 0; i < sl.size; ++i)
	{
		cout << SLAt(sl, i) << " ";

	}
	cout << endl;
	SLAt(sl, 0)++;
		SLAt(sl, 0) = 10;
	for (int i = 0; i < sl.size; ++i)
	{
		cout << SLAt(sl, i) << " ";

	}
	cout << endl;
	return 0;
}

你可能感兴趣的:(c++,开发语言)