Contents

C++基础语法(二)

6 运算符

sizeof运算符

sizeof 运算符可用于获取类、结构、共用体和其他用户自定义数据类型的大小。

逗号运算符

整个逗号表达式的值为系列中最后一个表达式的值。从本质上讲,逗号的作用是将一系列运算按顺序执行。

逗号之前的自增表达式也会在逗号结束后执行!

1
2
3
4
5
6
// 运行完结果:count=19,incr=10,var=20
var = (count=19, incr=10, count+1);

// 结果:j=11,i=1010
j = 10;
i = (j++, j+100, 999+j);

成员运算符

.(点)运算符和 ->(箭头)运算符用于引用类、结构和共用体的成员。访问结构的成员时使用点运算符,而通过指针访问结构的成员时,则使用箭头运算符。例如,假设有下面的结构:

1
2
3
4
struct Employee {
  char first_name[16];
  int  age;
} emp;

点运算符:

1
strcpy(emp.first_name, "zara");

箭头运算符:

1
2
// p_emp 是一个指针,指向类型为 Employee 的对象
strcpy(p_emp->first_name, "zara");

强制转换运算符

1
2
double a = 21.09399;
int c = (int) a;	// 结果为21

指针运算符

取地址运算符 &:返回操作数的内存地址。

间接寻址运算符 *:返回操作数所指定地址的变量的值。

1
2
3
4
5
int  var = 3000;
int  *ptr;
int  val;
ptr = &var;	// 获取 var 的地址
val = *ptr;	// 获取 ptr 的值

7 循环

基于范围的for循环:

1
2
3
4
5
6
7
int my_array[5] = {1, 2, 3, 4, 5};
// 每个数组元素乘于 2
for (int &x : my_array)
{
    x *= 2;
    cout << x << endl;  
}

8 switch语句

  • switch 语句中的 expression 必须是一个整型或枚举类型,或者是一个 class 类型,其中 class 有一个单一的转换函数将其转换为整型或枚举类型。
  • 不是每一个 case 都需要包含 break。如果 case 语句不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止。

9 函数

函数声明

1
2
3
4
int max(int num1, int num2);

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

当您在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,您应该在调用函数的文件顶部声明函数。

函数参数

形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。当调用函数时,有三种向函数传递参数的方式:

传值调用

该方法把参数的实际值赋值给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。

指针调用

把参数的地址复制给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。

1
2
3
4
5
6
7
8
// 调用:swap(&a,&b)
void swap(int *x, int *y)
{
   int temp;
   temp = *x;    /* 保存地址 x 的值 */
   *x = *y;        /* 把 y 赋值给 x */
   *y = temp;    /* 把 x 赋值给 y */
}

引用调用

把引用的地址复制给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。

1
2
3
4
5
6
7
8
// 调用:swap(a,b)
void swap(int &x, int &y)
{
   int temp;
   temp = x; /* 保存地址 x 的值 */
   x = y;    /* 把 y 赋值给 x */
   y = temp; /* 把 x 赋值给 y  */
}

参数的默认值

定义一个函数,可以为参数列表中后边的每一个参数指定默认值。当调用函数时,如果实际参数的值留空,则使用这个默认值。

1
2
3
4
5
6
int sum(int a, int b=20)
{
  int result;
  result = a + b;
  return (result);
}

Lambda 函数与表达式

对匿名函数的支持,称为 Lambda 函数(也叫 Lambda 表达式)。

Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。Lambda 表达式具体形式如下:

1
2
3
4
5
6
7
8
// 一般形式
[capture](parameters)->return-type{body}
// 一般情况
[](int x, int y) -> int { int z = x + y; return z + x; }
// 无返回类型
[](int x, int y){ return x < y ; }
// 无参数
[]{ ++global_x; } 

在Lambda表达式内可以访问当前作用域的变量,这是Lambda表达式的闭包(Closure)行为。 与JavaScript闭包不同,C++变量传递有传值和传引用的区别。可以通过前面的[]来指定:

1
2
3
4
5
6
[]      // 沒有定义任何变量。使用未定义变量会引发错误。
[x, &y] // x以传值方式传入(默认),y以引用方式传入。
[&]     // 任何被使用到的外部变量都隐式地以引用方式加以引用。
[=]     // 任何被使用到的外部变量都隐式地以传值方式加以引用。
[&, x]  // x显式地以传值方式加以引用。其余变量以引用方式加以引用。
[=, &z] // z显式地以引用方式加以引用。其余变量以传值方式加以引用。

另外有一点需要注意。对于[=]或[&]的形式,lambda 表达式可以直接使用 this 指针。但是,对于[]的形式,如果要使用 this 指针,必须显式传入:

1
[this]() { this->someFunc(); }();

10 数字

数学运算

引用数学头文件 <cmath>可以使用C++内置的数学函数。

  • double log(double); 该函数返回参数的自然对数。
  • double pow(double, double); 假设第一个参数为 x,第二个参数为 y,则该函数返回 x 的 y 次方。
  • double sqrt(double); 该函数返回参数的平方根。
  • int abs(int); 该函数返回整数的绝对值。
  • double fabs(double); 该函数返回任意一个浮点数的绝对值。
  • double floor(double); 该函数返回一个小于或等于传入参数的最大整数。

随机数

关于随机数生成器,有两个相关的函数。一个是 rand(),该函数只返回一个伪随机数。生成随机数之前必须先调用 srand() 函数。

下面是一个关于生成随机数的简单实例。实例中使用了 time() 函数来获取系统时间的秒数,通过调用 rand() 函数来生成随机数:

1
2
3
4
5
6
7
8
int main ()
{
   // 设置种子
   srand( (unsigned)time( NULL ) );
   // 生成实际的随机数
   int j= rand();
   return 0;
}

11 数组

多维数组

1
2
3
4
5
6
7
8
int a[3][4] = {  
 {0, 1, 2, 3} ,   /*  初始化索引号为 0 的行 */
 {4, 5, 6, 7} ,   /*  初始化索引号为 1 的行 */
 {8, 9, 10, 11}   /*  初始化索引号为 2 的行 */
};

// 内部嵌套的括号是可选的,下面的初始化与上面是等同的:
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

指向数组的指针

1
2
3
4
5
6
double *p;
double runoobAarray[10];
// 把 p 赋值为 runoobAarray 的第一个元素的地址
p = runoobAarray;
// *(runoobAarray + 4) 是一种访问 runoobAarray[4] 数据的合法方式
// *(runoobAarray + 4) == *(p+4)

传递数组给函数

C++ 传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址。

如果您想要在函数中传递一个一维数组作为参数,您必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。同样地,您也可以传递一个多维数组作为形式参数。

  • 形式参数是一个指针:
1
void myFunction(int *param){}
  • 形式参数是一个已定义大小的数组:
1
void myFunction(int param[10]){}
  • 形式参数是一个未定义大小的数组:
1
void myFunction(int param[]){}

就函数而言,数组的长度是无关紧要的,因为 C++ 不会对形式参数执行边界检查。

从函数返回数组

C++ 不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 要生成和返回随机数的函数
int * getRandom( )
{
  static int  r[10];
  // 设置种子
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)
  {
    r[i] = rand();
  }
  return r;
}