C++基础句法

简介: ● 使用场景1.switch只能支持常量固定值相等的判断2.if还可以判断区间范围3.用switch能做的,用if都能做,但是反过来不行。

C++基础句法


三种基本程序结构

●  顺序、分支和循环


switch和if比较


●  使用场景


1.switch只能支持常量固定值相等的判断

2.if还可以判断区间范围

3.用switch能做的,用if都能做,但是反过来不行。


●  性能比较


1.分支少时候差别不大,分支多时,switch性能高

2.if开始处几个分支高效,之后递减

3.switch所有的case速度几乎一样。


循环语句

●  C++提供三种玄幻语句:while do while 和 for

#include <iostream>
using namespace std;
int main()
{   // TODO: 1+2+3+4...+100
  // while语句
  int sum = 0;
  int index = 1;
  while (index <= 100)
  {
    sum += index;
    index += 1;
  }
  //cout << sum << endl;
  // for语句
  //index = 1;
  sum = 0;
  for (index = 1; index <= 100; ++index)
  {
    sum += index;
  }
  //cout << sum << endl;
  // do-while语句
  sum = 0;
  index = 1;
  do 
  {
    sum += index;
    index += 1;
  } while (index <= 100);
  //cout << sum << endl;
    return 0;
}

自定义结构-枚举


●  使用#define和const创建符号常量,使用enum不仅能够创建符号常量,还能定义新的数据类型:


●  枚举类型enum的声明和使用 如:enum wT{Monday = 5, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};


●  使用细节


   ○  枚举值不可以做左值

   ○  非枚举类型不能赋值给枚举变量

   ○  枚举变量可以赋值给非枚举变量

#include <iostream>
using namespace std;
int main()
{
    enum wT{Monday = 5, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}; // 声明wT类型
    wT weekday;
    weekday = Monday;
    weekday = Tuesday;
    //weekday = 1;             // 不能直接给int值,只能赋值成wT定义好的类型值
    cout << weekday << endl;
    //Monday = 0;             // 类型值不能做左值
    int a = Wednesday;
    cout << a << endl;
    return 0;
}

自定义结构 - 结构体和联合体


●  使用struct定义结构体


●  使用union定义联合体


●  结构体的尺寸:


●  结构体对齐原则:缺省对齐原则


   ○  32位CPU:


   char : 任何地址


   short: 偶数地址


   int 4的整数倍地址


   double 4的整数倍地址


●  修改默认编译选项


   ○  msvc #pragma pack(1)

   ○  g++ __attribute__(aligned(n)) __attribute__(__packed__)

#pragma pack(1)
#include <string.h>
#include <iostream>
using namespace std;
int main()
{
    union Score
    {
        double ds;
        char level;
    };
    struct Student
    {
        char name[6];
        int age;
        Score s;
    };
    //cout << sizeof(Score) << endl;      // 8
    Student s1;
    strcpy_s(s1.name, "lili");
    s1.age = 16;
    s1.s.ds = 95.5;
    s1.s.level = 'A';
    cout << sizeof(Student) << endl;    // 24     18
    return 0;
}

函数

●  一个C++程序是由若干个源程序文件构成,而一个源程序是由若干个函数组成,函数将一段逻辑封装起来以便复用。

●  从用户角度看,函数分成:

   ○  库函数 标准函数,由C++提供 比如strcpy_s等

   ○  用户自定义函数:需要用户定义后使用。


函数的组成部分:


1.返回类型:一个函数可以返回一个值

2.函数名称:函数的实际名称,函数名和参数列表一起构成了函数签名;

3.参数:参数列表包括函数参数的类型、顺序、数量。参数时可选的,也就是说函数可能不包含命令参数;


函数重载overload与函数签名

int test(int a);
int test(double a);
int test(int a, double d);

指向函数的指针和返回指针的函数

●  每个函数都占用一段内存单元,它们有一个起始地址,指向函数入口地址的指针称为函数指针


例子: int (*p)(int);


●  注意与返回指针的函数的区别 int *p(int);

#include <iostream>
using namespace std;
int MaxValue(int x, int y)
{
  return (x > y) ? x : y;
}
int MinValue(int x, int y)
{
  return (x < y) ? x : y;
}
int Add(int x, int y)
{
  return x+y;
}
bool ProcessNum(int x, int y, int(*p)(int a, int b))
{
  cout << p(x, y) << endl;
  return true;
}
int main()
{   
  int x = 10, y = 20;
  cout << ProcessNum(x, y, MaxValue) << endl;
  cout << ProcessNum(x, y, MinValue) << endl;
  cout << ProcessNum(x, y, Add) << endl;
    return 0;
}

命名空间

using namespace std;


内联函数

如果一个函数是内联的,那么编译时候,编译器会把函数的代码副本放在每个调用函数的地方。

inline int max(int x, int y)
{
    return x>y?x:y;
}

内联函数内部不能处理太复杂的逻辑,编译器有时会有自己的优化策略,所以内联不一定有用。


递归

使用准则:


   1.基准情形:无需递归就能解出

   2.不断推进:每一次递归必须使求解状况接近基准情况方向推进

   3.设计法则:假设所有的递归调用都能运行

   4.合成效益法则:求解一个问题的同一个实例时,切勿在不同递归函数中做重复性工作。


递归的缺陷:


●  递归是一种重要的编程思想

   1.很多重要的算法都包含递归思想

   2.递归最大的缺陷

       1.空间上需要大量的栈空间

       2.时间上可能需要大量的重复运算


●  递归的优化:

   1.尾递归:所有的递归形式的调用都出现在函数的末尾

   2.使用循环代替

   3.使用动态规划,空间换时间

#include <assert.h>
#include <iostream>
int g_a[1000]; // 全局的数组,记录斐波那契数列的前1000个值
// 斐波那契数列的实现
// 方法一:递归
int Fib(int n)
{
  if (n == 0)
  {
    return 0;
  }
  else if (n == 1)
  {
    return 1;
  }
  else
  {
    return Fib(n - 1) + Fib(n - 2);
  }
}
// 尾递归
int Fib2(int n, int ret0,  int ret1)
{
  if (n == 0)
  {
    return ret0;
  }
  else if (n == 1)
  {
    return ret1;
  }
  return Fib2(n - 1, ret1, ret0 + ret1);
}
// 循环
int Fib3(int n)
{
  if (n < 2)
  {
    return n;
  }
  int n0 = 0, n1 = 1;
  int temp;
  for (int i = 2; i <= n; i++)
  {
    temp = n0;
    n0 = n1;
    n1 = temp + n1;
  }
  return n1;
}
// 动态规划
int Fib4(int n)
{
  //assert(n >= 0);
  g_a[0] = 0;
  g_a[1] = 1;
  for (int i = 2; i <= n; i++)
  {
    if (g_a[i] == 0)
    {
      g_a[i] = g_a[i - 1] + g_a[i - 2];
    }
  }
  return g_a[n];
}
int main()
{
  //Fib(10);
  //std::cout  << Fib2(10, 0, 1);
  //std::cout << Fib(20) << std::endl;
  //std::cout << Fib2(20, 0, 1) << std::endl;
  //std::cout << Fib3(20) << std::endl;
  //std::cout << Fib4(20) << std::endl;
  assert(Fib(10) == 55);
  assert(Fib2(10, 0, 1) == 55);
  assert(Fib3(10) == 55);
  assert(Fib4(10) == 55);
    return 0;
}


目录
相关文章
|
5月前
|
机器学习/深度学习 自然语言处理
词嵌入与语义表示
词嵌入与语义表示
|
7月前
|
机器学习/深度学习 移动开发 自然语言处理
基于BiLSTM-CRF模型的分词、词性标注、信息抽取任务的详解,侧重模型推导细化以及LAC分词实践
基于BiLSTM-CRF模型的分词、词性标注、信息抽取任务的详解,侧重模型推导细化以及LAC分词实践
基于BiLSTM-CRF模型的分词、词性标注、信息抽取任务的详解,侧重模型推导细化以及LAC分词实践
|
7月前
|
机器学习/深度学习 自然语言处理 算法
【Python自然语言处理】概率上下文无关文法(PCFG)及神经网络句法分析讲解(图文解释 超详细)
【Python自然语言处理】概率上下文无关文法(PCFG)及神经网络句法分析讲解(图文解释 超详细)
218 0
|
机器学习/深度学习 自然语言处理 搜索推荐
基于GCN和句法依存分析的情感分析
(1)构建/利用图结构 核心问题:针对某个特定任务构建一个图来使用潜在的信息。 因为有些任务中,图数据是给定的(如引用网络、社交网络、推荐系统的图数据等),但是有些图结构并不明显,所以需要转为一个图上可以解决的问题(如节点分类、链路预测等)。
591 0
基于GCN和句法依存分析的情感分析
|
机器学习/深度学习 人工智能 Java
概率统计——重要术语及解释
概率统计——重要术语及解释
概率统计——重要术语及解释
|
机器学习/深度学习 编解码 算法
语义分割项目详解
语义分割项目详解
357 0
语义分割项目详解
|
自然语言处理
词汇的逻辑<一>:政法(1)
词汇的逻辑<一>:政法(1)
词汇的逻辑<一>:政法(1)
|
机器学习/深度学习 自动驾驶 算法
语义分割入门
语义分割入门
368 1
语义分割入门
|
机器学习/深度学习 自然语言处理
论文赏析[TACL18]隐式句法树模型真的能学到句子中有意义的结构吗?(一)
本文是一篇分析类论文,主要对近年来几种无监督句法分析模型(RL-SPINN和ST-Gumbel)进行了分析,得出了如下三个结论: 在句子分类任务上,只有一种模型效果好于传统的树结构模型。 这些模型随机性很大,初始化不同,结果也都差距很大。 这些模型产生的句法树的平均深度比PTB数据集的平均深度浅。
148 0
论文赏析[TACL18]隐式句法树模型真的能学到句子中有意义的结构吗?(一)
|
机器学习/深度学习 自然语言处理
论文赏析[TACL18]隐式句法树模型真的能学到句子中有意义的结构吗?(二)
本文是一篇分析类论文,主要对近年来几种无监督句法分析模型(RL-SPINN和ST-Gumbel)进行了分析,得出了如下三个结论: 在句子分类任务上,只有一种模型效果好于传统的树结构模型。 这些模型随机性很大,初始化不同,结果也都差距很大。 这些模型产生的句法树的平均深度比PTB数据集的平均深度浅。
534 0
论文赏析[TACL18]隐式句法树模型真的能学到句子中有意义的结构吗?(二)