520 likes | 704 Views
C++ 程序语言设计. Chapter 3: The C in C++. OutLine of the chapter. Same thing in program language Make and Ant. 诸子百家 —— 名家. 名家是战国时期的重要学派之一,因从事论辩名(名称、概念)实(事实、实在)为主要学术活动而被后人称为名家。 http://www.guoxue.com/gxrm/gx_mingj.htm
E N D
C++程序语言设计 Chapter 3: The C in C++
OutLine of the chapter • Same thing in program language • Make and Ant
诸子百家——名家 • 名家是战国时期的重要学派之一,因从事论辩名(名称、概念)实(事实、实在)为主要学术活动而被后人称为名家。 http://www.guoxue.com/gxrm/gx_mingj.htm • 公孙龙(约公元前325—前250年),赵国人。生平事迹不详。他是名家代表人物之一,有14篇著作留世,但在唐时已散失了一大半,如今可能只《公孙龙子》一书。名家最著名的命题,是公孙龙的"白马非马"论。
“白马非马”论 • 庄子评:“能胜人之口,不能服人之心。” • 城门上告示:“马匹不得入城”。公孙龙同志骑白马而来,遭拒入。公孙龙一脸正色:“告示上写的是‘马’,而我骑的是‘白马’,难道 ‘马’等于 ‘白马’吗?”。守门士兵觉得白马还真不是马,于是放行。 • 如果白马是马,黑马也是马,那么岂不白马等于黑马,所以,不能说白马是马。“白马非马”是中国哲学史上的一桩公案。不过,若是我们从程序的角度上说,可以认为:马在这里表示一种类型,而白马,黑马它们的类型都是马。
Data types • 预定义数据类型(基本数据类型) • 字符型:char • 整型:int • 单精度浮点型:float • 双精度浮点型:double • 无值型:void • 布尔型:bool • 构造数据类型:指针、数组、结构、类等
Data types • 类型修饰符 • 在基本数据类型(除void与bool类型外)前加上类型修饰符,来更具体地表示数据类型。 • signed 有符号 • unsigned 无符号 • short 短型 • long 长型 • 阅读程序:specify.cpp
Data types • 类型修饰符说明 • 附件中带[ ]的部分表示是可以省略的,如short [int]可以写为short int 或简写为short,二者的含义是相同的。 • 四种修饰符都可以用来修饰整型和字符型。用signed修饰的类型的值可以为正数或负数,用unsigned修饰的类型的值只能为正数。 • 用short修饰的类型,其值一定不大于对应的整数,用long修饰的类型,其值一定不小于对应的整数。
运算符 功能 数据类型 例子 - 负号 数值 x=-y; + 加 数值 z=x+y; - 减 数值 z=x-y; * 乘 数值 z=x*y / 除 数值 z=x/y; % 求余 整数 z=x%y ++ 自加 数值 z++或++z Operators • 算术运算符
赋值运算符 例子 等价形式 = x=x+y x=x+y += x+=y+z x=x+(y+z) -= x-=y+z x=x-(y+z) *= x*=y+z x=x*(y+z) /= x/=y+z x=x/(y+z) %= x%=y+z x=x%(y+z) Operators • 赋值运算符
关系运算符 含义 例子 < 小于 i>10 <= 小于或等于 (x+y)*2<=100 > 大于 x+y>z >= 大于或等于 x-y>=a*b+2 = = 等于 x+y==a+b != 不等于 x-y!=0 Operators • 关系运算符
逻辑运算符 含义 例子 ! 逻辑非 !(x>10) && 逻辑与 (i>1) && (i<10) || 逻辑或 c==0 || c==9 Operators • 逻辑运算符
Operators • 三元运算符 在C++中只提供了一个三元运算符—即条件运算符“?:”,其一般形式为: 表达式1 ? 表达式2 : 表达式3 条件运算的规则是:首先判断表达式1的值,若其值为真(非0),则取表达式2的值为整个表达式的值;若其值为假(0),则取表达式3的值为整个表达式的值。
运算符 含义 例子 & 按位与 i&128 | 按位或 j|64 ^ 按位异或 j^12 ~ 按位取反 ~j << 按位左移 i<<2 >> 按位右移 j>>2 Operators • 位运算符
运算符 例子 等价形式 &= x&=y+z x=x&(y+z) |= x|=x+2 x=x|(x+2) ^= x^=y x=x^y <<= x<<=y+z x=x<<(y+z) >>= x>>=y+z x=x>>(y+z) Operators • 复合位运算符
Operators • 逗号运算符 逗号运算符的运算优先级是最低的。 一般形式为: 表达式1,表达式2,……,表达式N 在计算逗号表达式的值时,按从左至右的顺序依次分别计算各个表达式的值,而整个逗号表达式的值和类型是由最右边的表达式决定。
Operators • Operator precedence • use parentheses to make the order of evaluation explicit • A = X + Y – 2 / 2 + Z; • X = 1、Y = 2、Z = 3 • A = X + (Y – 2) / (2 + Z); • 阅读程序:Mathops.cpp
语句A 语句B Execution control statements • 顺序结构 • 程序按照语句的书写顺序依次执行,语句在前的先执行,语句在后的后执行,只能满足设计简单程序的要求。
条件P 语句A 语句B Execution control statements • 分支结构 • 在分支结构中,程序根据判断条件是否成立,来选择执行不同的程序段。也就是说,这种程序结构,能有选择地执行程序中的不同程序段。
Execution control statements • 分支结构 • if-else语句 • switch语句 switch(selector) { case integral-value1 : statement; break; case integral-value2 : statement; break; case integral-value3 : statement; break; (...) default: statement; }
假 条件P 真 语句A Execution control statements • 循环结构 • 在循环结构中,程序根据判断条件是否成立,来决定是否重复执行某个程序段。
Execution control statements • 循环结构 • while语句 • do-while语句 • for语句 • 跳转语句break • 继续语句continue • 关键字goto • 阅读程序:Menu.cpp、Menu2.cpp、gotoKeyword.cpp
Execution control statements • 递归算法 • 直接或间接地调用自身的算法称为递归算法。用函数自身给出定义的函数称为递归函数。 • “老和尚讲故事” • 要有终止条件,否则…… • 阅读程序:CatsInHats.cpp
Execution control statements • 递归算法 • 编写计算斐波那契数列的第n项函数fib(n): 斐波那契数列为:0、1、1、2、3、……,即: fib(0) = 0;fib(1) = 1; fib(n) = fib(n - 1) + fib(n - 2)(当n>1时) 写成递归函数为: int fib(int n){ if (n == 0) return 0; if (n == 1) return 1; if (n > 1) return fib(n - 1) + fib(n - 2); }
Execution control statements • 递归算法 • 计算某个数的阶乘就是用那个数去乘包括 1 在内的所有比它小的数。 • 阶乘的一个有趣特性是,某个数的阶乘等于该数乘以比它小一的数的阶乘。 int factorial(int n) { return n * factorial(n - 1); } int factorial(int n) { if(n == 1) return 1; else return n * factorial(n - 1); }
Functions • function prototyping • int translate(float x, float y, flaoat z); • empty argument list • func()、func(void) • uncertain argument list • creating your own libraries
Introduction to pointers • the ‘&’ operator precede the identifier name with ‘&’ and it will produce the address of that identifier. see “YourPets1.cpp” • pointer definition For a type T , T * is the type“ pointer to T”, that is , a variable of type T * can hold the address of an object of type T.
Introduction to pointers • The operator that defines a pointer ‘*’ • Insert a star ‘*’ between the type and the identifier int* ip; // ip points to an int value int a = 47; int* ipa = &a; *ipa = 100;
Introduction to pointers • the most basic use of pointers To change “outside objects” from within a function. • Ordinarily, when you pass an argument to a function, a copy of that argument is made inside the function. This is referred to as pass-by-value. • see “PassByValue.cpp”
Introduction to pointers • want to modify the outside object pass a pointer into a function instead of an ordinary value, we are actually passing an alias to the outside object, enabling the function to modify that outside object. This is referred to as pass-by-address. see “PassAddress.cpp”
Introduction to C++ references Pointers work roughly the same in C and in C++, but C++ adds an additional way to pass an address into a function. This is pass-by-reference . see “PassReference.cpp”
Introduction to C++ references • A reference is an alternative name for an object. • we must initialize the reference while define it. int i = 1; int& r1 = i; // ok, r1 initialized int& r2; // error, miss initializer extern int& r3; // ok, r3 initialized elsewhere
Pointer to void • void * : pointer to any type of object. int main() { void* vp; char c; int i; float f; double d; vp = &c; vp = &i; vp = &f; vp = &d; } ///:~
Pointer to void • before you can use the pointer void *, you must cast it to the correct type int main() { int i = 99; void* vp = &i; // Can't dereference a void pointer: // *vp = 3; // Compile-time error // Must cast back to int before dereferencing: *((int*)vp) = 3; } ///:~
Scoping The scope of a variable extends from the point where it is defined to the first closing brace that matches the closest opening brace before the variable was defined. That is, a scope is defined by its “nearest” set of braces. see “Scope.cpp”
Defining variables on the fly • C++ (not C) allows you to define variables anywhere in a scope, so you can define a variable right before you use it. • Define variables inside the control expressions of for loops and while loops, inside the conditional of an if statement, and inside the selector statement of a switch.
Global variables • Global variables are defined outside all function bodies and are available to all parts of the program (even code in other files). • Global variables are unaffected by scopes and are always available see “Global.cpp” and “Global2.cpp”
Local variables • register variables • static variables • The beauty of a static variable is that it is unavailable outside the scope of the function, so it can’t be inadvertently changed. see” Static.cpp” • The second meaning of static is related to the first in the “unavailable outside a certain scope” sense. “file scope ” see “FileStatic.cpp” and “FileStatic2.cpp”
Constants and volatile • #define PI 3.14159 • The modifier const tells the compiler that a name represents a constant. Any data type, built-in or user-defined, may be defined as const. If you define something as const and then attempt to modify it, the compiler will generate an error. const float PI = 3.1415926;
Constants and volatile Whereas the qualifier const tells the compiler “This never changes” ,the qualifier volatile tells the compiler “You never know when this will change”.
Casting operators • C Style • 类型转换操作符 (type-id) expression int b=10; long a = (long) b; • 函数调用语法 type-id( expression ) int b=10; long a = long(b);
Casting operators • C++ Style-四个类型转换符 • static_cast • const_cast • reinterpret_cast • dynamic_cast
static_cast • 用法:static_cast < type-id > ( expression )该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。 • 它主要有如下几种用法:①用于类层次结构中基类和子类之间指针或引用的转换。②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。③把空指针转换成目标类型的空指针。④把任何类型的表达式转换成void类型。 see static_cast.cpp
const_cast • 用法:const_cast<type_id> (expression)该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。 • 用法: • 常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象; • 常量对象被转换成非常量对象。 see const_cast.cpp
reinterpret_cast • 用法:reinpreter_cast<type-id> (expression)type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。 see reinterpret_cast.cpp
dynamic_cast • 用法:dynamic_cast < type-id > ( expression )该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。 • dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
sizeof operator • tells us the number of bytes used by any particular variable • an operator, not a function • apply it to a variable you can use it without parentheses see sizeofOperator.cpp, sizeof.cpp
Composite type creation • Aliasing names with “typedef ” Form : typedef existing-type-description alias-name Example: int* x, y; typedefint* IntPtr; IntPtr m, n;
Combining variables with struct • The struct declaration must end with a semicolon. • To select the elements of a particular struct object, use a ‘.’ • a pointer to a struct object, you must select an element of that object using a different operator: the ‘->’ SimpleStruct2.cpp, SimpleStruct3.cpp
Clarifying programs with enum • a way of attaching names to numbers • enumerates any list of identifiers you give it by assigning them values of 0, 1, 2, etc • enum ShapeType { circle = 10, square = 20, rectangle = 50 }; • enum snap { crackle = 25, pop }; see Enum.cpp
Saving memory with union • handle different types of data using the same variable • two choices : • create a struct containing all the possible different types you might need to store • use a union. A union piles all the data into a single space see Union.cpp