目录
前言:
大家好呀,这里是我对c++在学习类和对象前的一些基础的理解(〃'▽'〃) 希望大家能够指正出我的错误,我们一起共同进步!
下面会介绍了解的是c++语法中的命名空间、输入输出、缺省参数、函数重载、引用、内联函数、auto、范围for、nullptr等....
好啦,话不多说,直接开始吧~
命名空间:
1.关键字:namespace 2.使用规范:namspace 名字{} 里面可以定义变量和函数
3.作用:在此命名空间定义的变量名可以和其他的变量名区分开。
namespace Test
{
void Print()
{
printf("这里是Test\n");
}
int id = 1;
}
void Print()
{
printf("这里是自由-\n");
}
int main()
{
int id = 0;
printf("%d\n", id);
printf("%d\n", Test::id);
Print();
Test::Print();
}
4.::域作用限定符,左边没有的话默认访问全局域,对应的访问左边的域内
5.如果不需要指定,可以使用using namespace 名字;将其展开:
namespace Test
{
void Print()
{
printf("这里是Test\n");
}
int id = 1;
int _id = 2;
}
void Print()
{
printf("这里是自由-\n");
}
using namespace Test;
int main()
{
int id = 0;
printf("%d\n", id);//就近原则 优先访问局部变量
printf("%d\n", _id);//已经展开了
printf("%d\n", Test::id);//同样需要指定
::Print();//这里展开同个函数参数表相同不构成重载,所以访问全局域
Test::Print();
}
6.遵循就近原则。
7.如果只是暴露一部分,可以使用using Test::(想暴露的属性名);
8.同时发现c++一样可以使用c语言里的printf,说明c++和c语法兼容。
输入输出:
1.首先明确std是C++标准库的命名空间
2.iostream是std命名空间的头文件
3.C++中的输出输入在std命名空间内有其cout和cin对象调用
4.<<流插入 用于将要输出到控制台上的内容串联起来。如果是基本数据类型则自动识别类型。
5.>>流提取 用于将键盘中的内容提取到变量之中。也是自动识别类型。
#include<iostream>
using namespace std;//将标准库直接展开来
int main()
{
cout << "这里是C++程序哦~" << endl;
int year;
cout << "现在是多少年呢? ";
cin >> year;
cout << endl << "现在是" << year << "年呢" << endl;
return 0;
}
6.endl同样存在于std命名空间内,可以理解为"\n",同样的在字符串内输入\n实现同样的效果。
7.如果不展开std库的话(做项目的时候不能全部展开)那么有两种方法:
1.在对象名前加上std名,表示从此域中去找。(不推荐)
2.只展开std中的cout、cin、endl常用的几个就可以了。(推荐)
using std::cout;
//using std::cin;
using std::endl;
int main()
{
int year = 0;
cout << "这里是C++程序哦~" << "\n";//只展开std中的cout
//cin >> year;//没有展开std中的cin单独使用找不到其定义
std::cin >> year;//指定std域就好了
cout << "现在是" << year << "年啦" << endl;
return 0;
}
缺省参数:
C ++中有着默认给形参初值的语法,这样会方便处理很多问题。
1.若在函数声明的时候形参赋给的有值,那么在调用时不给其赋值则利用其值。(声明和定义一起就直接写,分离以声明为准)
2.全缺省:一个函数里面所有形参均有赋给初值。
3.半缺省:(注意不是一半哦~)部分参数缺省,但是遵循顺序:从右到左来连续。
4.注意调用函数的时候实参给形参遵循从左到右。
//注:在此文件开头已经将std展开,日常练习使用可以展开(方便)
void Test1(int a = 0)//全缺省
{
cout << "------------------Test1-------------------\n";
cout << "a ==" << a << endl;
}
void Test2(int b = 0, int c = 0)//全缺省
{
cout << "------------------Test2-------------------\n";
cout << "b ==" << b << endl;
cout << "c ==" << c << endl;
}
void Test3(int b, int c = 0)//半缺省
{
cout << "------------------Test3-------------------\n";
cout << "b ==" << b << endl;
cout << "c ==" << c << endl;
}
void Test4(int a, int b = 0, int c = 0)//半缺省
{
cout << "------------------Test4-------------------\n";
cout << "a ==" << a << endl;
cout << "b ==" << b << endl;
cout << "c ==" << c << endl;
}
//void Test5(int b = 0, int c)//存在问题,缺省默认从右边开始来连续
//{
//
//}
int main()
{
Test1();//不传参调用缺省参数
Test1(1);
Test2();
Test2(1, 2);
//Test3();//此时不是全省,必须传一个参数
Test3(1);
Test3(1, 2);
Test4(0);//同理
Test4(9, 8);
Test4(9, 8, 7);
return 0;
}
下面实现声明和定义分离缺省函数的实现:
//Test.h
#pragma once
#include<iostream>
using namespace std;
void Test(int a = 0);//必须声明实现缺省
void Test2(int a);//如果声明不实现缺省,就无法实现缺省
//Test.cpp
#include"Test.h"//里面是Test含有其缺省声明
void Test(int a)//定义内不需要缺省
{
cout << "a == " << a << endl;
}
void Test2(int a = 0)//定义内不需要缺省
{
cout << "a == " << a << endl;
}
//main.cpp
#include"Test.h"//里面是Test含有其缺省声明
int main()
{
Test();
Test(2);
//Test2();//声明定义分离定义里缺省不行 报错可以自己试试
Test2(3);
return 0;
}
函数重载:
为了方便调用函数实现类似的功能,而不是利用符号和数字进行区别,所以函数重载,横空降临~
1.相同函数名,返回值可以不同,但是形参列表必须不同。(这样调用的时候才能区分)
2.只是返回值不同的话不构成重载。
3.可以了解到的是输入输出利用所谓的自动识别实际上就是函数重载
int Add(int num1, int num2)
{
return num1 + num2;
}
//double Add(int num1, int num2)//只是返回值不同不构成重载哦
//{
// return num1 + num2;
//}
double Add(int num1, double num2)//参数列表不同
{
return num1 + num2;
}
double Add(double num1, int num2)//顺序不同同理
{
return num1 + num2;
}
double Add(double num1, double num2)
{
return num1 + num2;
}
int main()
{
cout << Add(1, 1) << endl;
cout << Add(1, 1.5) << endl;
cout << Add(1.25, 1) << endl;
cout << Add(1.2, 1.5) << endl;
return 0;
}
引用:
指针有时候使用和理解起来会有一定的复杂性,为了减轻这种复杂,C++加入了引用这一全新的语法,可以类比于起别名。
1.引用格式 数据类型& = 变量;(数据类型即为此变量的类型或者比其权限小的类型,不可权限放大)
2.定义的时候必须初始化。3.一个变量可以有多个引用,但是一个引用只能指向一个实体,之后不能指向其他。
int main()
{
int a = 1;
int& _a = a;//定义的同时就要初始化
int b = 0;
_a = b;//一个引用只能指向一个实体,所以此时相当于将b的值给a
int& __a = a;
int& ___a = a;//一个变量可以有多个引用
cout << a << endl;
_a = 2;
cout << a << endl;
//可以打印它们的地址可以发现均代表a
cout << &a << endl;
cout << &_a << endl;
cout << &__a << endl;
cout << &___a << endl;
return 0;
}
4.注意:只能权限平移,权限缩小,不能权限放大。
int main()
{
int a = 10;
int& _a1 = a;//权限平移
const int& _a2 = a;//权限降低
//double& _a3 = a;
const int b = 12;//常变量属性
const int& _b1 = b;//权限平移
//int& _b2 = b;//权限不可放大
return 0;
}
5.特别的,注意int转成double进行类型提升的时候,原本的int类型变量是不会发生改变的,中间会出现一个临时变量用来接收提升后的变量的值,临时变量具有常量属性。
6.对此,引用也可以给常量起别名,const就是修饰常量属性的。(不可改变)
int main()
{
int a = 10;
double b = a;//提升
//double& _a1 = a;//不行,此时引用针对的是临时变量,具有常属性
const double& _a2 = a;//加上const即可
const int& cc = 10;//因此可用来给常量起别名
return 0;
}
7.应用场景:
--做参数 & 输出型参数--
1.比如交换函数就可以代替指针
--做返回值 & 不是局部变量--
2.返回一个不随函数调用完毕回收内存的情况(比如static),比如方便修改数组中的某个值,堆内存中。
8.注意,引用底层实现逻辑还是指针。引用必须要初始化,并且专一(只指向一个实体),指针更加强大,但是不安全。引用局限,但是安全。
void Swap(int& num1, int& num2)//交换函数利用引用实现
{
int temp = num1;
num1 = num2;
num2 = temp;
}
int& Test()
{
static int a = 10;
return a;
}
int main()
{
int a = 1, b = 0;
cout << "a = " << a << ", b = " << b << endl;
Swap(a, b);
cout << "a = " << a << ", b = " << b << endl;
cout << Test() << endl;
Test() = 12;//传引用返回
cout << Test() << endl;
return 0;
}
内联函数:
每次遇到代码很少,但是需要多次重复调用的函数是不是非常影响效率呀,针对c语言里面可以使用宏来定义,但是存在很多的缺陷,所以,C++就推出了内联函数这个概念。
1.关键字:inline 2.编译时使用此关键只是给编译器建议此函数在此展开,不进行压栈操作。
3.编译器一般看其指令的(汇编)的量来决定,一般是10行左右。
4.inline是一种使用性关键字,如果只在声明处标志,那么不会链入符号表。所以一般在定义前使用。inline_百度百科 (baidu.com)
inline void Test()
{
cout << "Test" << endl;
}
int main()
{
Test();
return 0;
}
5.需要注意的是,在debug版本下,如果查看是否展开的话会发现还是调用的,因为为了方便调试,转函数,如果需要查看需要进行一些设置。
6.C语言里面利用的是宏,但是要注意格式:#define ADD(a, b) ((a)+(b))
7.C语言宏函数的优缺点:宏的优点:a、代码复用性变强(宏常量) b、宏函数提高效率,不建立栈帧缺点:a、可读性差 b、没有类型安全检查 c、不方便调试
#define ADD(x, y) ((x) + (y))
int main()
{
cout << ADD(1 ^ 2, 3) << endl;//此处凸显了(x)这个括号的作用,防止优先级问题影响正常结果
cout << ADD(1, 2) * 2 << endl;//此处凸显了外层括号的作用,防止出现只是后面数与其相乘而不是整体相乘影响结果
}
8.C++中建议使用 const enum inline来代替宏的作用。
auto、范围for、nullptr:
C++中也有自动识别类型的哦~,范围for可以更加快捷方便的遍历哦,C++中将NULL可设置成了数字0,所以有时候使用就会出现问题,为了解决这个问题,提出了nullptr来代替NULL。
1.auto自动推导类型,可以使用typeid(变量名).name() ---->类型名来进行检测。
2.需要注意,auto不能想基本类型那样多行赋值,并且不能作为参数,因为编译的时候给函数开空间需要知道其类型。不能声明数组
int main()
{
auto a = 10.4f;
cout << typeid(a).name() << endl;
return 0;
}
3.范围for利用auto和:进行自动加加,自动赋值达到简洁的遍历作用。但是:右边的数组不可修改,左边的可传值,可传引用进行更多的操作。
int main()
{
int a[] = { 1, 2 ,3, 4, 5 };
for (auto e : a)
{
cout << e << " ";
}
cout << endl;
return 0;
}
4.C++里面NULL可以代表0,有些时候会出现一些问题,针对于此,可以使用nullptr代替NULL的作用。
int main()
{
int* a = NULL;
int* b = nullptr;
int d = NULL;
cout << d << endl;
return 0;
}
未完待续......更多内容期待你的补充!