C++ 程程程程程程 Chapter 3: The C in C++
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修饰的类型,其值一定不小于对应的整数。
Operators 算术运算符
运算符 功能 数据类型 例子- 负号 数值 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 三元运算符 在 C++ 中只提供了一个三元运算符—即条件运算符“?:”,其一般形式为: 表达式 1 ? 表达式 2 : 表达式 3 条件运算的规则是:首先判断表达式 1 的值,若其值为真(非 0 ),则取表达式 2 的值为整个表达式的值;若其值为假( 0 ),则取表达式 3 的值为整个表达式的值。
Operators 位运算符
运算符 含义 例子& 按位与 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 逗号运算符 逗号运算符的运算优先级是最低的。 一般形式为: 表达式 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
Execution control statements 顺序结构
程序按照语句的书写顺序依次执行,语句在前的先执行,语句在后的后执行,只能满足设计简单程序的要求。语句 A
语句 B
Execution control statements 分支结构
在分支结构中,程序根据判断条件是否成立,来选择执行不同的程序段。也就是说,这种程序结构,能有选择地执行程序中的不同程序段。
条件P语句
A语句
B
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;}
Execution control statements 循环结构
在循环结构中,程序根据判断条件是否成立,来决定是否重复执行某个程序段。
真 假条件
P语句
A
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 definitionFor 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 valueint 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 initializedint& r2; // error, miss initializerextern 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 typeint 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;} ///:~
ScopingThe 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 volatileWhereas 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-nameExample:
int* x, y;typedef int* 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
Arrays select array elements starting at zero index past the end of the array, there
is no safety net must define the size of the array at
compile time and when you give the name of an
array, without square brackets, what you get is the starting address of the array
谁能告诉我?什么是 QT?