【C++】内联函数&auto关键字&基于范围的for循环&指针空值

内联函数&auto关键字&基于范围的for循环&指针空值

  • 内联函数
    • 内联函数的使用
  • auto关键字
    • 使用注意事项
  • 基于范围的for循环
  • 指针空值

内联函数

在c语言中,我们使用宏定义可以定义两种类型,分别是宏常量和宏函数,而在定义宏常量和宏函数时,会遇到一些奇奇怪怪的问题,例如当我们非常小心的使用宏函数,加了许多括号,但是依然很容易出现错误,例如

【C++】内联函数&auto关键字&基于范围的for循环&指针空值_第1张图片

在上述代码中,按照我们对其理解,返回的应该是较小的值,res应该为10,但是实际结果确是==12。这是宏函数在被展开后,直接进行了替换,而++x这个值被自增了两次导致的结果,因此宏函数的使用非常可能会出错。这样的例子在宏常量也经常出现。
因此在c++中对宏常量和宏函数都进行了修改,将宏常量使用const进行替换(实际是扩展了const的属性),将宏函数使用内联函数进行替换。

内联函数的使用

需要使用内联函数时,将函数以inline进行修饰,编译时c++编译器会将函数在调用内联函数的地方展开,这样的方式实际上以空间换时间的做法,因为会使得目标文件变大,代码膨胀。
另外,inline只是一个对编译器的建议,建议函数规模较小的函数,不是递归或频繁调用的函数进行内联函数的调用,反之编译器可能会选择忽略使用内联函数的建议。
并且使用inline进行内联函数的调用时,一般不建议将申明和定义分开,因为这样会造成链接错误。

宏的优缺点
优点:增强代码的复用性、提高性能
缺点:不方便调试宏、代码可读性差可维护性差、没有类型安全的检查

替换的方法
常量定义 换成const
宏函数 替换为内联函数

auto关键字

在c语言中,经常会遇到各种各样复杂的数据类型,这使得在coding的时候,思考这个数据类型是什么非常头疼,因此在c++中为了解决复杂数据类型定义书写困难,修改了auto关键字的含义,auto作为一个类型提示符来指示编译器,auto声明的变量必须由编译器在编译阶段推到而来。

使用注意事项

//1.auto与指针和引用结合起来使用
int main()
{
 int x = 10;
 auto a = &x;
 auto* b = &x;
 auto& c = x;
 cout << typeid(a).name() << endl;
 cout << typeid(b).name() << endl;
 cout << typeid(c).name() << endl;
 *a = 20;
 *b = 30;
 c = 40;
 return 0;
}
//2.在同一行定义多个变量
void TestAuto()
{
 auto a = 1, b = 2; 
 auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}
//3.不能作为函数的参数,也不能直接用来声明数组
void TestFor(int array[])
{
 for(auto& e : array)
 cout<< e <<endl;
}

基于范围的for循环

在c语言中,如果我们要进行一个for循环,通常是这样做的

void TestFor()
{
 int array[] = { 1, 2, 3, 4, 5 };
 for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
 array[i] *= 2;
 
 for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)
 cout << *p << endl;
}

但是这样做的存在一个弊端,如果判断条件错误,就非常容易出现数组越界的情况,而针对一个有范围的集合,程序员说明循环的范围是多此一举的,并且还容易出错,因此c++中针对有范围的集合,对for循环做出了修改,在for循环中,使用:将函数需要传递的参数分为两部分,:前用于迭代的变量,:后是被迭代的范围

void TestFor()
{
 int array[] = { 1, 2, 3, 4, 5 };
 for(auto& e : array)
 e *= 2;
 
 for(auto e : array)
 cout << e << " ";
 
 return 0;
}

指针空值

在c语言中,定义一个指针变量的时候如果未对其进行初始化,那么会产生野指针,所以当指向未明确时,我们一般会将其指向NULL,但是实际上NULL是一个宏定义,为字面常量0,例如在c++中使用函数重载时,可能会产生误解

void f(int)
{
 cout<<"f(int)"<<endl;
}
void f(int*)
{
 cout<<"f(int*)"<<endl;
}
int main()
{
 f(0);
 f(NULL);
 f((int*)NULL);
 return 0;
}

这时候当我们给f函数传参为NULL时,编译器会认为我们传的是int类型的字面值0,因此会调用第一个f函数,这样就出现了错误,为了避免这样的问题出现,c++中将指针空值nullptr作为新的关键字引入。
那么上述代码使用nullptr时就不会出现误解了。

你可能感兴趣的:(C++,c++)