C++是一种静态类型、编译式的、大小写敏感的、支持过程化编程、面向对象编程和泛型编程。
C++被认为是一种中级语言,它综合了高级语言和低级语言的特点。
C++完全支持面向对象程序化设计,包括面向对象开发的四大特征:封装、抽象、继承、多态
对象 - 对象具有状态和行为。例如:一只狗的状态-颜色、名称、品种,行为-摇动、叫唤、吃。对象是类的实例。
类 - 类可以定义为描述对象行为/状态的模板/蓝图。
方法 - 一个方法是一种行为。一个类可以包含多个方法。可以在方法中写入逻辑、操作数据及执行所有的动作。
即时变量-每个对象都有其独特的即时变量。对象的状态是由这些即时变量的值创建。
类型 | 关键字 |
---|---|
布尔型 | bool |
字符型 | char |
整形 | int |
浮点数 | float |
双精度 | double |
无类型 | void |
宽字符型 | wchar_t |
类型 | 位 | 范围 |
---|---|---|
char | 1 个字节 | -128 到 127 或者 0 到 255 |
unsigned char | 1 个字节 | 0 到 255 |
signed char | 1 个字节 | -128 到 127 |
int | 4 个字节 | -2147483648 到 2147483647 |
unsigned int | 4 个字节 | 0 到 4294967295 |
signed int | 4 个字节 | -2147483648 到 2147483647 |
short int | 2 个字节 | -32768 到 32767 |
unsigned short int | 2 个字节 | 0 到 65,535 |
signed short int | 2 个字节 | -32768 到 32767 |
long int | 4 个字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
signed long int | 8 个字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
unsigned long int | 8 个字节 | 0 到 18,446,744,073,709,551,615 |
float | 4 个字节 | 精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字) |
double | 8 个字节 | 双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字) |
long double | 16 个字节 | 长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字。 |
wchar_t | 2 或 4 个字节 | 1 个宽字符 |
typedef声明
可以使用typedef为一个已有的类型取一个新的名字。
typedef type newname;//语法
typedef int feet;//告诉编译器feet是int的另一个名称
feet distance;//创建一个整型变量是distance
枚举类型
枚举类型是C++中一种派生数据类型,它是由用户定义若干枚举常量的集合。
如果一个变量只有几种可能的值,可以定义为枚举类型。所谓“枚举”是指变量的值一一列举出来,变量的值只能在列举出来的值的范围类。
创建枚举,需要关键字enum。枚举类型的一般形式为:
enum 枚举名{
标识符[=整形常量],
标识符[=整形常量],
...
标识符[=整形常量],
}枚举变量;
如果枚举没有初始化,即省掉“=整形常数”时,则从第一个标识符开始。
例如,下面的代码定义一个颜色枚举,变量c的类型为color。最后,c被赋值为“blue”。
enum color = {red,green,bule} c;
c = blue;
默认情况下,第一个名称值为0,第二个为1,以此类推,但也可以给名称赋予一个特殊的值,只需添加一个初始值即可。
enum color {red,grenn=5,blue};
在这里,blue的值是6,应为默认情况下,每个名称都会比它前面一个名称大1,但是red的值仍为0。
基于前一章讲解的基本类型,有以下几种基本的变量类型:
类型 | 描述 |
---|---|
bool | 存储值 true 或 false。 |
char | 通常是一个字符(八位)。这是一个整数类型。 |
int | 对机器而言,整数的最自然的大小。 |
float | 单精度浮点值。单精度是这样的格式,1位符号,8位指数,23位小数。 |
double | 双精度浮点值。双精度是1位符号,11位指数,52位小数。 |
void | 表示类型的缺失。 |
wchar_t | 宽字符类型。 |
C++也允许定义其他类型的变量,比如枚举、指针、数组、引用、数据结构、类等等。
储存类定义C++程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。C++程序中可用的存储类:static 、extern 、mutable 、thread_local(c++11)
static储存类
static储存类指示编译器在程序的生命周期内保持局部变量存在,而不需要在没次进入和离开作用域是进行创建和销毁。因此,使用static修饰局部变量可以在函数调用之间保持局部变量的值。
static修饰符也可以应用于全局变量。当static修饰全局变量是,会使变量的作用域限制在声明它的文件内。
#include
// 函数声明
void func(void);
static int count = 10; /* 全局变量 */
int main()
{
while(count--)
{
func();
}
return 0;
}
// 函数定义
void func( void )
{
static int i = 5; // 局部静态变量
i++;
std::cout << "变量 i 为 " << i ;
std::cout << " , 变量 count 为 " << count << std::endl;
}
编译结果:
变量 i 为 6 , 变量 count 为 9
变量 i 为 7 , 变量 count 为 8
变量 i 为 8 , 变量 count 为 7
变量 i 为 9 , 变量 count 为 6
变量 i 为 10 , 变量 count 为 5
变量 i 为 11 , 变量 count 为 4
变量 i 为 12 , 变量 count 为 3
变量 i 为 13 , 变量 count 为 2
变量 i 为 14 , 变量 count 为 1
变量 i 为 15 , 变量 count 为 0
extern储存类
extern储存类是用于提供一个全局变量的引用,全局全局变量对所有的程序文件都是可见的。当使用‘extern’时,对于无法初始化的变量,会把变量名指向一个之前定义过的储存位置。
#include
int count;
extern int count;
int main(){
void write_extern(void);
{
count = 5;
std::cout << "Count is " << count << std::endl;
}
}
运行结果:
Count is 5
mutable储存类
mutable 说明符仅适用于类的对象,它允许对象的成员代替常量。也就是说,mutable成员可以通过const成员函数修改。
tread_local储存类
使用thread_local说明符声明变量仅可在它其上创建的线程上访问。变量再创建线程是创建,并在销毁线程时销毁。每个线程都有其自己的变量副本。
thread_local说明符可用与static或extern合并。
算数运算符:
运算符 | 描述 | 实例 |
---|---|---|
+ | 把两个操作数相加 | A + B 将得到 30 |
- | 从第一个操作数中减去第二个操作数 | A - B 将得到 -10 |
* | 把两个操作数相乘 | A * B 将得到 200 |
/ | 分子除以分母 | B / A 将得到 2 |
% | 取模运算符,整除后的余数 | B % A 将得到 0 |
++ | 自增运算符,整数值增加 1 | A++ 将得到 11 |
– | 自减运算符,整数值减少 1 | A-- 将得到 9 |
#include
using namespace std;
int main()
{
int a = 21;
int b = 33;
int c;
c = a + b;
cout << "Line 1 - c 的值 " << c << endl;
c = a - b;
cout << "a - b的值 " << c << endl;
c = a * b;
cout << "a * b " << c << endl;
int d = 20;
c = ++d;
cout << "自增 " << c << endl;
}
输出结果:
Line 1 - c 的值 54
a - b的值 -12
a * b 693
自增 21
关系运算符
运算符 | 描述 | 实例 |
---|---|---|
== | 检查两个操作数的值是否相等,如果相等则条件为真。 | (A == B) 不为真。 |
!= | 检查两个操作数的值是否相等,如果不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) 不为真。 |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) 为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) 不为真。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A <= B) 为真。 |
逻辑运算符
运算符 | 描述 | 实例 |
---|---|---|
&& | 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 | (A && B) 为假。 |
|| | 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 | (A || B) 为真。 |
! | 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 | !(A && B) 为真。 |
位运算符
假设如果 A = 60,且 B = 13,现在以二进制格式表示,它们如下所示:
A = 0011 1100
B = 0000 1101
运算符 | 描述 | 实例 |
---|---|---|
&(按位与) | 同时为1取1,否则为0 | (A & B) 将得到 12,即为 0000 1100 |
|(按位或) | 只要有1就取1,否则为0 | (A|B)将的到61,即为 0011 1101 |
^(按位异或) | 不同为1,相同为0 | (A ^ B) 将得到 49,即为 0011 0001 |
~(按位取反) | 0变1,1变0 | (~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。 |
<< | 左移 | A << 2 将得到 240,即为 1111 0000 |
>> | 右移 | A >> 2 将得到 15,即为 0000 1111 |
赋值运算符
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符,把右边操作数的值赋给左边操作数 | C = A + B 将把 A + B 的值赋给 C |
+= | 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 | C += A 相当于 C = C + A |
-= | 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 | C -= A 相当于 C = C - A |
*= | 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 | C *= A 相当于 C = C * A |
/= | 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 | C /= A 相当于 C = C / A |
%= | 求模且赋值运算符,求两个操作数的模赋值给左边操作数 | C %= A 相当于 C = C % A |
<<= | 左移且赋值运算符 | C <<= 2 等同于 C = C << 2 |
>>= | 右移且赋值运算符 | C >>= 2 等同于 C = C >> 2 |
&= | 按位与且赋值运算符 | C &= 2 等同于 C = C & 2 |
^= | 按位异或且赋值运算符 | C ^= 2 等同于 C = C ^ 2 |
|= | 按位或且赋值运算符 | C |= 2 等同于 C = C | 2 |
杂项运算
运算符 | 描述 |
---|---|
sizeof | sizeof 运算符返回变量的大小。例如,sizeof(a) 将返回 4,其中 a 是整数。 |
Condition ? X : Y | 条件运算符。如果 Condition 为真 ? 则值为 X : 否则值为 Y。 |
, | 逗号运算符会顺序执行一系列运算。整个逗号表达式的值是以逗号分隔的列表中的最后一个表达式的值。 |
.(点)和 ->(箭头) | 成员运算符用于引用类、结构和共用体的成员。 |
Cast | 强制转换运算符把一种数据类型转换为另一种数据类型。例如,int(2.2000) 将返回 2。 |
& | 指针运算符 &如 &a; 将给出变量的实际地址。 |
* | 指针运算符 指向一个变量。例如,*var; 将指向变量 var。 |
C++中的运算符优先级
类别 | 运算符 | 结合性 |
---|---|---|
后缀 | () [] -> . ++ - - | 从左到右 |
一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 |
乘除 | * / % | 从左到右 |
加减 | + - | 从左到右 |
移位 | << >> | 从左到右 |
关系 | < <= > >= | 从左到右 |
相等 | == != | 从左到右 |
位与 AND | & | 从左到右 |
位异或 XOR | ^ | 从左到右 |
位或 OR | | | 从左到右 |
逻辑与 AND | && | 从左到右 |
逻辑或 OR | || | 从左到右 |
条件 | ?: | 从右到左 |
赋值 | = += -= *= /= %=>>= <<= &= ^= |= | 从右到左 |
逗号 | , | 从左到右 |
循环类型 | 描述 |
---|---|
while 循环 | 当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。 |
for 循环 | 多次执行一个语句序列,简化管理循环变量的代码。 |
do…while 循环 | 除了它是在循环主体结尾测试条件外,其他与 while 语句类似。 |
嵌套循环 | 您可以在 while、for 或 do…while 循环内使用一个或多个循环。 |
控制语句 | 描述 |
---|---|
break 语句 | 终止 loop 或 switch 语句,程序流将继续执行紧接着 loop 或 switch 的下一条语句。 |
continue 语句 | 引起循环跳过主体的剩余部分,立即重新开始测试条件。 |
goto 语句 | 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句。 |
无限循环
如果条件永远为真,则循环将变成无限循环。
#include
using namespace std;
int main()
{
for (;;)
{
printf("This loop will run forver.\n");
}
return 0;
}
注意:按Ctrl + C 终止循环。
判断语句 | 描述 |
---|---|
if语句 | 一个if语句由一个布尔表达式后面跟一个或多个语句组成。 |
if…else语句 | else语句在布尔表达式为假时执行。 |
嵌套if语句 | 可以在一个if或else if 语句内使用另一个if或else if 语句。 |
switch语句 | 一个switch语句允许测试一个变量等于多个值时的情况。 |
嵌套switch语句 | 可以在一个switch语句内使用另一个switch语句。 |
函数是一组一起执行一个任务的语句。每个C++程序至少有一个函数,即主函数main()。
函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供函数的实际主体。
定义函数
函数声明
函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
函数声明包括以下几个部分:
return_type function_name(parameter list);
针对上面定义的函数max(),以下是函数声明:
int max(int num1,int num2);
在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效声明:
int max(int,int);
当你在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必须的。在这种情况下,应该在调用函数的文件顶部声明函数。
调用函数
#include
using namespace std;
// 函数声明
int max(int num1, int num2);
int main ()
{
// 局部变量声明
int a = 100;
int b = 200;
int ret;
// 调用函数来获取最大值
ret = max(a, b);
cout << "Max value is : " << ret << endl;
return 0;
}
// 函数返回两个数中较大的那个数
int max(int num1, int num2)
{
// 局部变量声明
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
运行结果:
Max value is : 200
函数参数
如果函数要使用参数,则必须声明接受参数的变量。这些变量称为函数的形式参数。
形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。
调用类型 | 描述 |
---|---|
传值调用 | 该方法把参数的实际值赋值给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。(默认状态) |
指针调用 | 该方法把参数的地址赋值给形式参数。在函数内,该地址用于反问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。 |
引用调用 | 该方法把参数的引用赋值给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。意味着,修改形式参数会影响实际参数。 |
#include
using namespace std;
int sum(int a, int b=20)
{
int result;
result = a + b;
return (result);
}
int main ()
{
// 局部变量声明
int a = 100;
int b = 200;
int result;
// 调用函数来添加值
result = sum(a, b);
cout << "Total value is :" << result << endl;
// 再次调用函数
result = sum(a);
cout << "Total value is :" << result << endl;
return 0;
}
运行结果:
Max value is : 200
#include
using namespace std;
int main ()
{
// 数字定义
short s;
int i;
long l;
float f;
double d;
// 数字赋值
s = 10;
i = 1000;
l = 1000000;
f = 230.47;
d = 30949.374;
// 数字输出
cout << "short s :" << s << endl;
cout << "int i :" << i << endl;
cout << "long l :" << l << endl;
cout << "float f :" << f << endl;
cout << "double d :" << d << endl;
return 0;
}
输出结果:
short s :10
int i :1000
long l :1000000
float f :230.47
double d :30949.4
在C++中,除了可以创建各种函数,还包含内置函数。我们可以引用这些函数。
序号 | 函数 & 描述 |
---|---|
1 | double cos(double); 该函数返回弧度角(double 型)的余弦。 |
2 | double sin(double); 该函数返回弧度角(double 型)的正弦。 |
3 | double tan(double); 该函数返回弧度角(double 型)的正切。 |
4 | double log(double); 该函数返回参数的自然对数。 |
5 | double pow(double, double); 假设第一个参数为 x,第二个参数为 y,则该函数返回 x 的 y 次方。 |
6 | double hypot(double, double); 该函数返回两个参数的平方总和的平方根,也就是说,参数为一个直角三角形的两个直角边,函数会返回斜边的长度。 |
7 | double sqrt(double); 该函数返回参数的平方根。 |
8 | int abs(int); 该函数返回整数的绝对值。 |
9 | double fabs(double); 该函数返回任意一个浮点数的绝对值。 |
10 | double floor(double); 该函数返回一个小于或等于传入参数的最大整数。 |
#include
#include
using namespace std;
int main()
{
int a = 10;
int b = 20;
cout << "pow: " << pow(a, b) << endl;
cout << "abs: " << abs(a) << endl;
cout << "sin: " << sin(a) << endl;
cout << "sqr: " << sqrt(a) << endl;
}
运行结果:
pow: 1e+20
abs: 10
sin: -0.544021
sqr: 3.16228
随机生成器,两个相关的函数。一个是rand(),该函数返回一个伪随机数。生成随机数之前必须先调用**srand()**函数。
#include
#include
#include
using namespace std;
int main()
{
int i, j;
// 设置种子
srand((unsigned)time(NULL));
for (i = 0; i < 10; i++)
{
j = rand();
cout << "生成的第" << i+1 << "个数字是:" << j << endl;
}
}
输出结果:
生成的第1个数字是:30910
生成的第2个数字是:2007
生成的第3个数字是:26940
生成的第4个数字是:25453
生成的第5个数字是:31339
生成的第6个数字是:17076
生成的第7个数字是:10300
生成的第8个数字是:18920
生成的第9个数字是:1486
生成的第10个数字是:26703
#include
using namespace std;
#include
using std::setw;
int main ()
{
int n[ 10 ]; // n 是一个包含 10 个整数的数组
// 初始化数组元素
for ( int i = 0; i < 10; i++ )
{
n[ i ] = i + 100; // 设置元素 i 为 i + 100
}
cout << "Element" << setw( 13 ) << "Value" << endl;
// 输出数组中每个元素的值
for ( int j = 0; j < 10; j++ )
{
cout << setw( 7 )<< j << setw( 13 ) << n[ j ] << endl;
}
return 0;
}
运行结果:
Element Value
0 100
1 101
2 102
3 103
4 104
5 105
6 106
7 107
8 108
9 109
注:1.setw() 用于控制输出之间的间隔。
2.默认为右对齐,设置左对齐:cout << left<< setw(4) <<“1”
3.默认空,设置* :cout< C++中数组详解 C风格字符串 字符串实际上是使用null字符’\0’终止的一维字符数组。因此,一个以null结尾的字符串,包含了组成字符串的字符。 下面的声明和初始化创建了一个“Hello”字符串。由于在数组的末尾储存了空字符,所以字符数组的大小比单词“Hello”的字符数多一个。 依据数据初始化规则,您可以把上面的语句写成以下语句: 运算结果: 运算结果: 运行结果: 运行结果: 什么是指针 指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。 指针的声明 C++指针详解 引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字,一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。 C++引用 vs 指针 C++中创建引用 试想变量名称是变量附属在内存位置中的标签,您可以把引用当成是变量附属在内存位置中的第二个标签。因此,可以通过原始变量名称或引用来访问变量内容。 为i声明引用变量。 在这些声明中,&读作引用。因此,第一个声明可以读作“r是一个初始化为i的整形引用”。 运行结果: I/O库头文件 标准输出流(cout) cout 对象"连接"到标准输出设备,通常是显示屏 输出结果: 标准输入流(cin) cin 对象附属到标准输入设备,通常是键盘。 输出结果: 标准错误流(cerr) cerr 对象附属到标准错误设备,通常也是显示屏,但是 cerr 对象是非缓冲的,且每个流插入到 cerr 都会立即输出。 运行结果: 标准日志流 clog 对象附属到标准错误设备,通常也是显示屏,但是 clog 对象是缓冲的。这意味着每个流插入到 clog 都会先存储在缓冲在,直到缓冲填满或者缓冲区刷新时才会输出。 定义结构 访问结构成员 输出结果: typedef 关键字 下面是一种更简单的定义结构的方式,您可以为创建的类型取一个"别名"。例如: 现在,您可以直接使用 Books 来定义 Books 类型的变量,而不需要使用 struct 关键字。下面是实例: 您可以使用 typedef 关键字来定义非结构类型,如下所示: x, y 和 z 都是指向长整型 long int 的指针。
概念
描述
多维数组
C++支持多维数组。多维数组最简单的是二维数组。
指向数组的指针
通过指定不带索引的数组名称来生成一个指向数组中第一个元素的指针。
传递数组的函数
通过指定不带索引的数组名称来给函数传递一个指向数组的指针。
从函数返回数组
C++允许从函数返回数组。
C++字符串
char greeting[6] = {'H','e','l','o','\0'};
char greeting[] = "Hello";
#include
Greeting message: Hello
序号
函数&目的
1
strcpy_s(s1,s2);
复制字符串s2到字符串s1。
2
strcat_s(s1,s2);
连接字符串s2到字符串s1的末尾。
3
strlen(s1);
返回字符串s1的长度。
4
strcmp(s1,s2);
如果s1和s2是相同的,则返回0,如果s1
5
strchr(s1,‘el’);
返回一个指针,指向字符串s1中字符’el’的第一次出现的位置。
6
strstr(s1,s2);
返回一个指针,指向字符串s1中字符串s2的第一次出现的位置。#include
strcpy_s( str3, str1) : hello
strcat_s(str1,str2):helloworld
strlen(str1):10
strcmp(str1, str2):-1
strchr(str1, 'el'):lloworld
strstr(str1,tr2): world
C++中的String类
#include
str3 :Hello
str1 + str2: Helloworld
str3.size() : 10
C++指针
#include
var1 变量的地址:00EFF8C4
var2 变量地址:00EFF8B0 //不同电脑储存地址各不同
int *ip; /* 一个整型的指针 */
double *dp; /* 一个 double 型的指针 */
float *fp; /* 一个浮点型的指针 */
char *ch; /* 一个字符型的指针 */
概念
描述
C++ Null 指针
C++ 支持空指针。NULL 指针是一个定义在标准库中的值为零的常量。
C++ 指针的算术运算
可以对指针进行四种算术运算:++、–、+、-
C++ 指针 vs 数组
指针和数组之间有着密切的关系。
C++ 指针数组
可以定义用来存储指针的数组。
C++ 指向指针的指针
C++ 允许指向指针的指针。
C++ 传递指针给函数
通过引用或地址传递参数,使传递的参数在调用函数中被改变。
C++ 从函数返回指针
C++ 允许函数返回指针到局部变量、静态变量和动态内存分配。
C++引用
int i = 17;
int& r = i;
double& s = d;
#include
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7
概念
描述
把引用作为参数
C++ 支持把引用作为参数传给函数,这比传一般的参数更安全。
把引用作为返回值
可以从 C++ 函数中返回引用,就像返回其他数据类型一样。
C++基本的输入输出
头文件
函数和描述
该文件定义了 cin、cout、cerr 和 clog 对象,分别对应于标准输入流、标准输出流、非缓冲标准错误流和缓冲标准错误流。
该文件通过所谓的参数化的流操纵器(比如 setw 和 setprecision),来声明对执行标准化 I/O 有用的服务。
该文件为用户控制的文件处理声明服务.
#include
Hello
#include
请输入你的昵称: code 你的昵称是: code
#include
Error message: Type errorr
#include
Error message: Type errorr
C++数据结构
struct Books
{
char title[50];//标题
char author[50];//作者
char subject[100];//类目
int book_id;//书的ID
} book;
#include
第一本书标题:C++基础
第一本书作者:唐浩明
第一本书目录:编程基础
第一本书ID: 121
第二本书标题:算法之美
第二本书作者:克里斯丁
第二本书目录:算法解析
第二本书ID: 130
typedef struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
}Books;
Books Book1, Book2;
typedef long int *pint32;
pint32 x, y, z;