c++入门
Posted fengkun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++入门相关的知识,希望对你有一定的参考价值。
1. C++中关键字
2. 命名空间:概念以及使用方式
3. 缺省参数:概念、分类、注意事项
4. 函数重载:
函数重载概念、函数重载调用原理、C语言支持函数重载吗?为什么? extern "C"的作用
5. 引用:
C语言中函数有几种传参方式?优缺点
引用的概念以及特性
const类型引用
引用的使用场景
传值、地址、引用效率方面的比较
引用和指针的区别
6. 内联函数
内联函数的概念、特性以及注意事项
总结内联函数与宏函数的区别
7. C++11语法糖
auto类型推导
范围for循环
控制指针nullptr
C++中的关键字: 98 版本C++关键字有63个。不同版本有所不同。 命名空间:因为C / C++中要命名大量的变量、函数名和类的名称,容易造成命名冲突或名字污染,所以提出命名空间,来解决这些问题。 (理解成在逻辑上将名字的保存空间划分成不同区域。)。 命名空间以namespace关键字来定义,后面跟命名空间的名字,然后接一对。 定义命名空间有三种方式 : 普通命名空间 嵌套命名空间 同名命名空间合并。 普通命名空间 namespace Name1 //Name是命名空间的名字 命名空间中乐意定义变量、函数 int a; int Sum(itn x, int y) return x + y; 嵌套命名空间 namespace A1 int a; int b; int test(); namespace A2 int x; int y; 同工程中的同名命名空间,编译器会将其合并。 namespace N int a; int Add(int n, int m) return n + m; namespace N int x; int y; 命名空间的使用方式:1 域名加作用域限定符 N::a 2 using将命名空间成员引入 using N1::a 3 using namespace将命名空间引入 using namespace N namespace N1 int a; int b; int Add(int n, int m) return n + m; 1 域名加作用域限定符 N1::a void main() printf("%d\n", N::a); 2 using将命名空间成员引入 using N1::a using N1::b; void main() printf("%d\n", b); 3 using namespace将命名空间引入 using namespace N using namespace N1; void main() int c=Add(1, 2); printf("%d\n", c); 缺省参数:声明或定义函数时设置的默认值,没用实参时函数用该默认值作为参数值,有实参则用实参。 全缺省参数:函数中所有参数都带有默认值。 全缺省参数函数传值时从从前往后传参,没有实参的就用默认值作参数值。 半缺省参数:部分参数带有默认值,函数参数列表从右往左给默认值,从左往右传参。 缺省值不能同时在声明和定义中给出,必须单独在声明或定义其中一个给出。 缺省值只能是常量或者全局变量。 全缺省 void fun(int a = 2, int b = 3, int c = 4, int d = 4); 板缺省 必须从左往右依次设默认值,不能间隔着给默认值。 void fun2(int a , int b , int c = 4, int d = 4); void fun2(int a , int b=4 , int c , int d = 4); //错误 void fun2(int a=2, int b =4, int c, int d ) //错误 函数重载 :一个函数名定义多个功能相同,形参列表不同的函数,用来处理功类似但数据类型或要求不同的问题。 C++中 同一作用域中几个功能类似的同名函数,形参列表不同(参数类型、个数、顺序不同都可以)。 int Add(int a, int b) return a + b; double Add(double a, double b) return a + b; 函数重载:必须在相同的作用域, 相同名字的函数,参数列表不同。与返回值类型是否相同无关。 编译器在编译阶段,编译器对实参的类型进行推演, 根据推演的实参类型的结果选择调用合适的函数。 C语言不支持重载,因为C语言编译时对函数名的处理是加_ 如Add函数处理成 _Add,不管函数参数类型。 如果C语言中函数名重复,那么系统将无法区分。 C++能重载是因为C++在编译时,将函数类型和函数名一起处理区分。 extern"C"的作用是将函数按照C语言的规则进行编译。 void TestFunc() 2与1是参数个数不同 2 void TestFunc(int a) 3 void TestFunc(int a, double b) 3与4不同:参数类型次序 4 void TestFunc(double a, int b) 2和5参数的类型 5 int TestFunc(char a) return 0; 6 char TestFunc(char a) return a; int main() int ret1 = TestFunc(‘a‘); ///编译报错,返回值的类型不能构成重载条件,必须是参数列表不同。 char ret2 = TestFunc(‘b‘); TestFunc(‘c‘); return 0; 引用:給已经定义的变量再定义一个名字,引用变量不开辟内存空间,和原变量是一个内存空间(小名和学名是同一个人)。 引用类型必须和原变量(引用实体)的类型相同 (学名和小名的不能把一个人变成妖怪)。 引用定义是必须初始化 (取别名可定是针对已经存在的人)。 一个变量可以有多个引用 (人在不同的地方,周围的人对他的称呼可以有很多种 )。 (一个作用域中)引用一旦一个实体,不能再引用其它实体 (女朋友叫你男朋友,不能再叫别人男朋友。哇哈哈哈)。 类型& 名字 = 原变量名 void testRef() int a = 5; int& ra=a; const int& ra2 = a; //不能通过ra2来修改a (参考const修饰指针的规则) const int b = 3; int& rb = b; //编译报错,const int 无法转化为 int& const int c = 4; const int& rc = c; //编译通过,所以const修饰的变量引用时也要用const修饰。 const int& rrc = rc; //编译通过,可以对引用进行引用操作。 const int& rc = b; //错误 int& rc = a; //错误 一个引用只能对一个实体(变量)进行引用。 void testRef() const int a = 3; const int& ra = a; const int& rra=ra; //可以对引用再次引用。 cout << &a << " " << &ra << " " << &rra << endl; double b = 12.21; int main() testRef(); system("pause"); return 0; 引用的应用场景 引用可以做函数参数、返回值 void Swap(int& a, int& b) int temp = a; a = b; b = temp; int& Add(int a, int b) int c = a + b; return c; int main() int a = 3; int b = 5; int& ret = Add(a, b); printf("%d\n",ret); Add(1, 2); cout << ret << endl; //ret的值变成3,是因为函数调用时会将返回值传到这个空间。 system("pause"); //不能用栈上的空间作为引用类型返回。 return 0; 传值、传引用 传值作为函数的参数或返回值时,不会直接传递实参或返回变量本身,而是将实参或变量临时拷贝一份传递,效率很低。 引用作为函数的形参:如果想要通过形参改变外部实参---传递普通类型引用。 如果不想要通过形参改变外部实参---传递const类型引用。 引用作为函数的返回值类型。 如果按照引用方式进行返回,一定不能返回栈上的空间。 返回变量的生命周期不受函数结束的影响。 传引用和指针的运行效率是差不多的,二者都比传值的效率高很多, 引用不开辟空间,但是底层中,引用的处理方式就是指针的处理方式。 引用与指针的区别:引用不开辟新空间,指针要开辟自己的空间。 引用必须初始化,指针可以不初始化。 引用在引用一个实体后不能再引用其它实体,而指针可以随时修改所指向的同类型变量。 没有空引用,有空指针。 sizeof中引用的大小是所引用的实体的类型的大小,而指针是一个地址空间所占字节的大小。 引用加1是引用的实体加1,指针加1是指针所指位置往后偏移一个所指变量的类型字节数。 有多级指针,没有多级引用 (c++11 右引用?) 访问实体时指针要解引用,而引用是编译器自己处理。 引用比指针更安全 内联函数 用inline修饰的函数,编译时在调用内联函数的地方展开,不用压栈。内联函数是以空间换时间,提升程序运行效率。 代码很长或者有循环递归时不适合用内联函数, 内联函数 inline不要将声明和定义分离,inline被展开红藕函数没有地址,会导致链接错误 inline void Swap(int a, int b); 内联函数与宏函数的区别:内联函数做参数类型检查,而宏函数不做参数类型检查 内联函数不用中断调用,编译时可以镶嵌到目标代码中,而宏只是简单地字符替换 宏的优点:增强代码复用性,一改全改提高性能,提高性能。 宏的缺点:不方便调试,因为编译时进行了字符替换,导致代码可读性差,可维护性差,容易误用,没有类型安全检查 C++中替代宏的方法:常量定义加const修饰 函数用内联函数 C++11中的 auto 关键字 auto 修饰的变量,编译器根据初始化表达式来推导变量的实际类型,auto 是类型声明的“占位符”。而不是类型声明。 (理解为帮同学占个座位,来的是哪个宿舍的同学就说这儿坐的是哪个宿舍的人),编译后将auto换为实际类型。 auto 使用细则:1、与指针和引用结合使用时,auto和auto* 没有区别, auto& 则必须加上 & 2、在同一行定义多个变量,必须是同类型,编译器根据第一个变量值来进行推导,用推导出来的类型定义后面的变量 3、auto 定义的变量必须初始换,根据初始化值来推导,没有初始化则无法推导。 auto不能推导的情况: 不能做为函数的参数,编译器无法对函数实参的类型进行推导。 不能用来声明数组。 基于范围的 for 循环 (C++11) int main() int arr[4] = 1, 2, 3, 4 ; for (int i = 0; i < 4; ++i) cout << arr[i] << " "; cout << "\n"; for 循环语法 auto& e 表示定义一个用于迭代的变量,第二部分表示迭代的范围(此处为数组arr) 可以用 continue 结束本次循环 ,也可以用 break 跳出整个循环 for (auto& e : arr) cout << e<< " "; system("pause"); return 0; 范围for的使用条件:范围确定 迭代的对象要实现++或者==的操作 指针空值用 nullptr (C++11)
int *p = nullptr
以上是关于c++入门的主要内容,如果未能解决你的问题,请参考以下文章
少儿编程C++入门01:开发工具(小学生也能学的C++入门教程)每天五分钟,学会c++