C++ Memorandum

2020-02-29  本文已影响0人  minhelloworld

作为一名对自身职业充满热爱的Android工程师,C/C++的重要性不言而喻,以图镇楼,提醒自己~


android_structure.png

1、基本路线

1.1、数据类型

1)一些基本类型可以使用一个或多个类型修饰符进行修饰:

2)typedef 声明

您可以使用 typedef 为一个已有的类型取一个新的名字。下面是使用 typedef 定义一个新类型的语法:

typedef type newname; 

例如,下面的语句会告诉编译器,feet 是 int 的另一个名称:

typedef int feet;

feet distance;

上面的声明是完全合法的,它创建了一个整型变量 distance:

1.2、存储类

1) auto

2) static

3)extern

1.3、循环

1)for

1.4、函数

1)函数声明

在函数声明中,参数的名称并不重要,只有参数的类型是必需的,比如如下两种声明等价:

int max(int num1, int num2);
int max(int, int);
2)函数参数

当调用函数时,有三种向函数传递参数的方式:

调用类型 描述
传值调用 该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。
指针调用 该方法把参数的地址复制给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
引用调用 该方法把参数的引用复制给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
3)参数的默认值
int sum(int a, int b=20){
  int result; 
  result = a + b;
  return (result);
}
 
int main (){
   // 局部变量声明
   int a = 100;
   int result;
   // 再次调用函数
   result = sum(a);
   cout << "Total value is :" << result << endl;
   return 0;
}
4)typedef函数指针

形式:typedef 返回类型 (*新类型)(参数表)

typedef char (*PTRFUN)(int); 
PTRFUN pFun; 
char glFun(int a){ return;} 
void main() 
{ 
    pFun = glFun; 
    (*pFun)(2); 
}
#include <stdio.h>
#include <assert.h>
 
typedef int (*FP_CALC)(int,int);//定义一个函数指针类型
 
int add(int a, int b)
{
    return a + b;
}
 
int sub(int a, int b)
{
    return a - b;
}
 
int mul(int a, int b)
{
    return a * b;
}
 
int div(int a, int b)
{
    return b ? a/b : -1;
}
 
//定义一个函数,参数为op,返回一个指针,该指针类型为拥有两个int参数、
//返回类型为int的函数指针。它的作用是根据操作符返回相应函数的地址
FP_CALC calc_func(char op)
{
    switch( op )
    {
    case '+':
        return add;
    case '-':
        return sub;
    case '*':
        return mul;
    case '/':
        return div;
    default:
        return NULL;
    }
    return NULL;
}
 
//s_calc_func为函数,它的参数是 op,   
//返回值为一个拥有两个int参数、返回类型为int的函数指针  
int (*s_calc_func(char op)) (int , int)
{
    return calc_func(op);
}
 
//最终用户直接调用的函数,该函数接收两个int整数,
//和一个算术运算符,返回两数的运算结果
int calc(int a, int b, char op)
{
    FP_CALC fp = calc_func(op);
    int (*s_fp)(int,int) = s_calc_func(op);//用于测试
 
    assert(fp == s_fp);// 可以断言这两个是相等的
 
    if(fp)
        return fp(a,b);
    else
        return -1;
}
 
void main()
{
    int a = 100, b = 20;
 
    printf("calc(%d, %d, %c) = %d\n", a, b, '+', calc(a, b, '+'));
    printf("calc(%d, %d, %c) = %d\n", a, b, '-', calc(a, b, '-'));   
  printf("calc(%d, %d, %c) = %d\n", a, b, '*', calc(a, b, '*'));   
  printf("calc(%d, %d, %c) = %d\n", a, b, '/', calc(a, b, '/')); 
}
5)C++ 11 Lambda表达式

1.5、数组

1)多维数组

#include <iostream>
using namespace std;
 
int main ()
{
   // 一个带有 5 行 2 列的数组
   int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
 
   // 输出数组中每个元素的值                      
   for ( int i = 0; i < 5; i++ )
      for ( int j = 0; j < 2; j++ )
      {
         cout << "a[" << i << "][" << j << "]: ";
         cout << a[i][j]<< endl;
      }
 
   return 0;
}

2)初始化数组

double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};

//如果省略掉了数组的大小,数组的大小则为初始化时元素的个数。:
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

1.6、字符串

C++ 提供了以下两种类型的字符串表示形式:

1)C 风格字符串

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char greeting[] = "Hello";
const char *greeting = "Hello";

C++ 中有大量的函数用来操作以 null 结尾的字符串:

序号 函数 & 目的
1 strcpy(s1, s2):复制字符串 s2 到字符串 s1。
2 strcat(s1, s2): 连接字符串 s2 到字符串 s1 的末尾。
3 strlen(s1): 返回字符串 s1 的长度。
4 strcmp(s1, s2): 如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回值小于 0;如果 s1>s2 则返回值大于 0。
5 strchr(s1, ch): 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
6 strstr(s1, s2): 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

1.7、指针

1)空指针

2)指针的算术运算

int main ()
{
   int  var[MAX] = {10, 100, 200};
   int  *ptr;
 
   // 指针中的数组地址
   ptr = var;
   for (int i = 0; i < MAX; i++)
   {
      cout << "Address of var[" << i << "] = ";
      cout << ptr << endl;
 
      cout << "Value of var[" << i << "] = ";
      cout << *ptr << endl;
 
      // 移动到下一个位置
      ptr++;
   }
   return 0;
}

3)指针 VS 数组

4)指针数组

5)指向指针的指针

int main ()
{
    int  var;
    int  *ptr;
    int  **pptr;
 
    var = 3000;
 
    // 获取 var 的地址
    ptr = &var;
 
    // 使用运算符 & 获取 ptr 的地址
    pptr = &ptr;
 
    // 使用 pptr 获取值
    cout << "var 值为 :" << var << endl;
    cout << "*ptr 值为:" << *ptr << endl;
    cout << "**pptr 值为:" << **pptr << endl;
 
    return 0;
}

1.8、引用

1)引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字;

2)引用 vs 指针

引用很容易与指针混淆,它们之间有三个主要的不同:

3)实例

int main ()
{
   // 声明简单的变量
   int    i;
   double d;
 
   // 声明引用变量
   int&    r = i;
   double& s = d;
   
   i = 5;
   cout << "Value of i : " << i << endl;
   cout << "Value of i reference : " << r  << endl;
 
   d = 11.7;
   cout << "Value of d : " << d << endl;
   cout << "Value of d reference : " << s  << endl;
   
   return 0;
}

// 当上面的代码被编译和执行时,它会产生下列结果:
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7

1.9、类

1)拷贝构造函数
2)构造函数初始化列表

构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。

TODO:https://www.runoob.com/w3cnote/cpp-construct-function-initial-list.html

2、知识积累

2.1、静态库和动态库

2.2、C++类型转换之reinterpret_cast

TODO:https://zhuanlan.zhihu.com/p/33040213

2.3、整型数字的表示

10 //普通的整型数字类型
10u //无符号数
10L //长整型数
012 // 八进制数
0xc // 十六进制数

2.4、初始化列表

与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段,示例:

struct foo
{
    string name ;
    int id ;
    foo(string s, int i):name(s), id(i){} ; // 初始化列表
};

初始化类的成员有两种方式,一是使用初始化列表,二是在构造函数体内进行赋值操作。使用初始化列表主要是基于性能问题,对于内置类型,如int, float等,使用初始化类表和在构造函数体内初始化差别不是很大,但是对于类类型来说,最好使用初始化列表,因为使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的。

除了性能问题之外,有些时场合初始化列表是不可或缺的,以下几种情况时必须使用初始化列表

另外需要注意一下,成员变量的初始化顺序问题。

3、零零散散

int main(int argc, char *argv[]) {
  std::cout << "Who goes with F\145rgus?\012" << std::endl;
}

最后输出的结果就是Who goes with Fergus?

4、参考

上一篇下一篇

猜你喜欢

热点阅读