C++学习笔记——002

不是公子的小白 / 2024-03-17 / 原文

  • 在一个类里建立一个 const 时,不能给他初值:
class foo{
public:
    foo():i(100){}
    
private:
    const int i=100; // 错误!!!
};


//可以通过这样的方式来进行初始化
foo::foo():i(100){}

 

class Test{
public:
    Test():a(0){}
    enum {size1=100,size2=200};
    
private:
    const int a;         //只能在构造函数初始化列表中初始化
    static int b;        //在类的实现文件中定义并初始化
    const static int c;  //与 static const int c;相同
};


//static成员变量不能在构造函数初始化列表中初始化,因为它不属于某个对象
int Test::b=0;


//注意:给静态成员变量赋值时,不需要加static修饰符,但要加cosnt
cosnt int Test::c=0;

 

  • 在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明: int max(int, int);

 

  • 参数的默认值:当您定义一个函数,您可以为参数列表中后边的每一个参数指定默认值。当调用函数时,如果实际参数的值留空,则使用这个默认值。请看下面的实例:
#include <iostream>


using namespace std;


int sum(int a, int b=20)
{
    int result;
    result = a + b;
    return (result);
}


int main ()
{
    // 局部变量声明
    int a = 100;
    int b = 200;
    int result;


    // 调用函数来添加值
    result = sum(a, b);
    cout << "Total value is :" << result << endl;


    // 再次调用函数
    result = sum(a);
    cout << "Total value is :" << result << endl;
    return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Total value is :300
Total value is :120

 

srand((unsigned)time(NULL));  //利用当前时钟可产生不同的随机数种子
j= rand();

 

  • 对于[]这种下标运算符,a[i]都是被解释为*(a+i)的。这是C语言中的一个规则,它把数组名和指针名视为等价的。你可以把[]看作是一种语法糖,它让你用更简洁的方式来访问数组元素,而不用写*和+。但是在编译器的眼中,它们都是一样的,它们都会被转换成指针运算。你可以用下面的公式来理解: a[i] = *(a + i) = *(i + a) = i[a] 。这里,a[i]和*(a+i)是等价的,它们都表示a加上i后所指向的地址处的值,也就是a的第i个元素。而*(i+a)和i[a]也是等价的,它们都表示i加上a后所指向的地址处的值,同样也是a的第i个元素。这里,i和a可以交换位置,因为加法运算是可交换的。你可能会觉得i[a]很奇怪,但是它确实是合法的C语言代码,只不过很少有人这么写。

 

  • C++ setw() 函数:用于设置字段的宽度,语法格式如下: setw(n) n表示宽度,用数字表示。setw() 函数只对紧接着的输出产生作用。当后面紧跟着的输出字段长度小于 n 的时候,在该字段前面用空格补齐,当输出字段长度大于 n 时,全部整体输出。

 

 

setw() 默认填充的内容为空格,可以 setfill() 配合使用设置其他字符填充。

#include <iostream>
#include <iomanip>
 
using namespace std;
 
int main()
{
    cout << setfill('*')  << setw(14) << "runoob" << endl;
    return 0;
}


//以上代码输出结果为:
//********runoob

 

  • C++ 从函数返回数组:C++ 不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。如果您想要从函数返回一个一维数组,您必须声明一个返回指针的函数,如下:
int * myFunction()
{
    //. . .
}

 

int* myFunction()
{
   int myArray[3] = {1, 2, 3};
   return myArray;
}

注意:你不能简单地返回指向局部数组的指针,因为当函数结束时,局部数组将被销毁,指向它的指针将变得无效。

 

C++ 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。为了避免以上情况,你可以使用静态数组或者动态分配数组。使用静态数组需要在函数内部创建一个静态数组,并将其地址返回,例如:

int* myFunction()
{
   static int myArray[3] = {1, 2, 3};
   return myArray;
}

 

  • C++ Null 指针:在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。NULL 指针是一个定义在标准库中的值为零的常量。
#include <iostream>


using namespace std;


int main ()
{
   int  *ptr = NULL;


   cout << "ptr 的值是 " << ptr ;
 
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

ptr 的值是 0

 

在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。

 

如需检查一个空指针,您可以使用 if 语句,如下所示:

if(ptr)       /* 如果 ptr 非空,则完成 */
if(!ptr)      /* 如果 ptr 为空,则完成 */

 

因此,如果所有未使用的指针都被赋予空值,就可以防止误用一个未初始化的指针。很多时候,未初始化的变量存有一些垃圾值,导致程序难以调试。

 

  • 使用初始化列表来初始化字段:
Line::Line( double len): length(len)
{
    cout << "Object is being created, length = " << len << endl;
}

上面的语法等同于如下语法:

Line::Line( double len)
{
    length = len;
    cout << "Object is being created, length = " << len << endl;
}

 

假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同理地,您可以使用上面的语法,只需要在不同的字段使用逗号进行分隔,如下所示:

C::C( double a, double b, double c): X(a), Y(b), Z(c)
{
  ....
}

 

  • 静态成员函数与普通成员函数的区别:静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数)。普通成员函数有 this 指针,可以访问类中的任意成员。

 

扫码关注公众号,查看更多精彩内容