\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[UTF8]{ctexcap}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}

\usepackage{xcolor}
%opening
\title{C++学习笔记}
\author{行走的芦苇}

\begin{document}

\maketitle

%\begin{abstract}

%\end{abstract}

\section{基本概念}
在协作完成一个大的软件时，应如何合理地设计程序结构，并保证每一个子程序之间都能正确地共享和交换数据，这是编程的\textcolor{red}{核心问题}。

程序员的任务是将计算表达出来，并且做到：
\begin{itemize}
 \item 正确
 \item 简单
 \item 高效
\end{itemize}
一个看似矛盾的事实：关注代码结构和代码“质量”是程序取得成功的最快捷径。\\
程序的组织体现了程序员的编程思路、目前手段主要是把大的计算任务划分为许多小任务，这一技术主要包括两类方法。
\begin{itemize}
 \item[抽象]：即不需要了解的程序具体实现细节被隐藏在相应的接口后边
 \item[分治]：把一个大问题分为几个小问题分别解决
\end{itemize}
对于一个好的程序员和系统设计师，软件的\textbf{结构问题}是在开发过程中始终要关注的最重要问题。

将问题不断的分解、细化，直到问题小到能够被我们很好的理解和解决为止\\
表达式是程序的最小组成单元，表达式就是从一些操作数计算一个值。\\
左值：一个变量；右值，一个变量的值\\
符号常量表示那些在初始化后值不再改变的数值量。\\
表达式语句主要包括赋值语句、I/O语句和函数调用。声明语句呢？？

除了合法输入情况以外，程序必须经过各种非法输入的检验。\\
switch语句括号中值必须是整型、字符型或枚举类型。特别的，不能使用字符串型\\
\begin{verbatim}
 char* ca = reinterpret_cast<char*>(&a);
\end{verbatim}
判定一个自然数是质量的方法：
对于任一自然数$N$，$0 <m <N-1$,若$ \frac{N}{m}\neq 0$，则$N$为质数。\par
\textbf{算法描述}
\begin{description}
 \item[输入]输入正整数$N$,$N>=3$
 \item[判定]对于$\forall M~~2<M<N-1$,若$N\%M == 0$，则$N$为质数。
\end{description}
\textcolor{red}{为什么vector不做越界检查呢？}

错误的来源：
\begin{itemize}
    \item 缺少规划，如果事先没有规划好程序做什么，就不能检查所有的“死角”，并确认所有可能的情况都会被正确处理
    \item 不完备的程序，不可能考虑所有可能的情况
    \item 意外的参数，如果为一个函数输入了一个不能处理的参数
    \item 意外的输入，键盘、文件、图形界面和网络都有可能出错
    \item 意外状态，多数程序都保留了很多系统的各个部分的状态，如果这些状态数据出错或不完整会导致程序出错
    \item 逻辑错误，程序没有按照我们期望的逻辑运行。
\end{itemize}
做过分析（理解问题）和设计（决定解决方案的整体结构）以后才进行程序设计。分析判断应该做什么并且给出对当前问题理解的描述，也称为需求集合或规范，设计给出系统的整体结构图，并确定具体的实现内容以及它们之间的相互关系，实现编写代码、调试并测试，确保程序完成预期的功能。

定义一个文法来定义表达式的语法，然后在程序中实现这些文法规则。

如何来读入一个文法呢？基本文法是这样的：对于给定输入，从顶层规则开始，搜索与输入单词匹配的规则。根据文法读取单词流的方式称为语法分析，实现的程序称为分析器或语法分析器。

阅读代码是积累编程技巧的有效途径。

尤其危险的程序是在很多情况下给出正确的结果。

最基本的做法是阅读代码并猜测错误在哪里，但通常这不是一个好方法。因为我们必须理解程序代码在做什么。错误分析通常也是能找出正确求解方案的最好方法。

类的定义主要说明类能够做什么，成员函数定义则指明如何做。

程序设计的本质：不断地寻找更简单的方法。

大多数程序设计概念是通用的，而很多这种概念被流行的程序设计语言所广泛支持。

声明(declaration)将名字引入作用域，其作用是：一是为命名实体指定一个类型；二（可选）是进行初始化。大致来说，一个声明定义了一些功能的使用方式，也就是，定义了函数、变量或类的接口。如果一个声明给出了声明实体的完整描述的话，我们称之为定义(definition)。定义是声明，但声明不是定义。这两者的区别反映出“如何使用一个实体（接口）”与“这个实体如何完成它应该做的事情”之间的根本区别。

很多愚蠢的错误都是在很忙或疲倦的时候发生的。

C++不允许我们对内置类型设置默认初始化功能，全局变量会被默认初始化为0,但应少使用全局变量。最常使用的变量--局部变量和类成员--是不会被初始化的，除非你对它进行初始化。

一个变量的作用域越大，名字就应该越长，越有描述性。

？：结构称作算术if(arithmetic if )或条件表达式(conditional expression)

形式参数：formal argument；参数：parameter

在函数声明中，形参的名字不是必需的，只是对于编写好的注释很有益处。

参数使用的基本原则：
\begin{itemize}
 \item 使用传值方式传递非常小的对象
 \item 使用传常量引用方式传递不需修改的大对象
 \item 让函数返回一个值，而不是修改通过引用参数传递来的对象
 \item 只有迫不得已时才使用传引用方式
\end{itemize}

实际参数：actual argument

尽量作用显示转换：\verb|static_cast<int>(x)|

当一个函数被调用时，编译器分配一个数据结构，保存所有参数和局部变量的拷贝，这样的数据结构称为函数活动记录(function activation record)，每个函数的活动记录都有自己特有的详细布局。

递归(recursive)

活动记录栈(stack of activation record)；调用栈(call stack)

一个constexpr函数和普通函数行为相同，但若在需要一个常量的位置处使用它，则有所不同，此时若传递的参数是常量表达式，则计算在编译时完成。为使该机制可行，要求constexpr函数必须非常简单。在C++11中，函数体只有包含一条return 语句；在C++14中，还可以写简单的循环语句。

一段代码中，创建变量的顺序与销毁的顺序相反。

\textcolor{red}{\verb|v[++i]=i|}是有很大的问题：不同的编译器不一定给出警告，不同的优化方法产生的结果可能不同，不能保证赋值符左边的子表达式一定先于右边的计算。
\begin{verbatim}
 //file1
 int x1 = 1;
 int y1 = x1+2

 //file2
 extern int y1;
 int y2 = y1 + 2;
\end{verbatim}
这段代码的问题是：使用了全局变量；全局变量名字太短；全局变量使用了复杂的初始化。\par
\begin{verbatim}
    const Data& default_date()
    {
        static const Deat dd(1970,1,2);
    }
\end{verbatim}
一个静态的局部变量只在首次调用时才被初始化；使用引用，消除了不必要的对象拷贝；使用常量引用，可以防止调用者无意中改变对象的值。



\section{编码错误}
\begin{verbatim}
 double my_abs(int  x)
{
    if (x < 0)
        return -x;
    else if (x > 0)
        return x;
}
\end{verbatim}
这种情况下，当$x=0$会返回无效值
\end{document}
