1.c++语言环境:
如果您使用的是 Linux 或 UNIX,请在命令行使用下面的命令来检查您的系统上是否安装了 GCC:
g++ -v
没有请安装
2.样例:
helloworld.cpp
#include
using namespace std;
int main()
{
cout << "Hello, world!" << endl;
return 0;
}
上述样例跑一个“Hello, world!”字样
编译:
g++ helloworld.cpp -o helloword
你将得到一个编译后的helloworld脚本
运行:
./helloworld
3.c++简介
1.C++ 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言,支持过程化编程、面向对象编程和泛型编程。
2.面向对象程序设计
3.具有标准库
4.程序结构:
#include
using namespace std;
// main() 是程序开始执行的地方
int main()
{
cout << "Hello World"; // 输出 Hello World
return 0;
}
接下来我们讲解一下上面这段程序:
该文件定义了 cin、cout、cerr 和 clog 对象,分别对应于标准输入流、标准输出流、非缓冲标准错误流和缓冲标准错误流
5.typedef 声明
您可以使用 typedef 为一个已有的类型取一个新的名字。下面是使用 typedef 定义一个新类型的语法:
typedef type newname;
例如,下面的语句会告诉编译器,feet 是 int 的另一个名称:
typedef int feet;
现在,下面的声明是完全合法的,它创建了一个整型变量 distance:
feet distance;
6.枚举类型
enum 枚举名{ 标识符[=整型常数], 标识符[=整型常数], ... 标识符[=整型常数] } 枚举变量;
例如,下面的代码定义了一个颜色枚举,变量 c 的类型为 color。最后,c 被赋值为 "blue"。
enum color { red, green, blue } c; c = blue;
默认情况下,第一个名称的值为 0,第二个名称的值为 1,第三个名称的值为 2,以此类推。但是,您也可以给名称赋予一个特殊的值,只需要添加一个初始值即可。例如,在下面的枚举中,green 的值为 5。
enum color { red, green=5, blue };
在这里,blue 的值为 6,因为默认情况下,每个名称都会比它前面一个名称大 1,但 red 的值依然为 0。
7.局部变量
#include
using namespace std;
int g = 10;
int func()
{
int g = 5;
return 5;
}
int main()
{
cout << "old = " << g << endl;
int g = 20;
int a = func();
cout << "new = " << g << endl;
return 0;
}
这里输出10,20
证明,全局变量谁都可以使用,局部变量只能自己内部使用
定义全局变量时,系统会自动初始化为下列值:
数据类型 |
初始化默认值 |
int |
0 |
char |
'\0' |
float |
0 |
double |
0 |
pointer |
NULL |
8.常量
两种方法:
1.#define a 注意没有;
2.const int a;
#include
using namespace std;
#define length 10
#define width 5
#define newline "\n"
int main()
{
int area = length * width;
cout << "area = " << area << newline << "------" << newline;
return 0;
}
#include
using namespace std;
const int length = 10;
const int width = 5;
int main()
{
float area = length * width;
cout << "area = " << area << "\n";
return 0;
}
9.修饰符类型
常用的修饰符:
signed
unsigned
long
short
#include
using namespace std;
/*
* 这个程序演示了有符号整数和无符号整数之间的差别
*/
int main()
{
short int i; // 有符号短整数
short unsigned int j; // 无符号短整数
j = 50000;
i = j;
cout << i << " " << j;
return 0;
}
10.限定符
限定符 |
含义 |
const |
const 类型的对象在程序执行期间不能被修改改变。 |
volatile |
修饰符 volatile 告诉编译器不需要优化volatile声明的变量,让程序可以直接从内存中读取变量。对于一般的变量编译器会对变量进行优化,将内存中的变量值放在寄存器中以加快读写效率。 |
restrict |
由 restrict 修饰的指针是唯一一种访问它所指向的对象的方式。只有 C99 增加了新的类型限定符 restrict。 |
11.存储类
存储类定义 C++ 程序中变量/函数的范围(可见性)和生命周期
static为全局变量声明关键字
extern用于预先声明一个变量,但是不赋值,值从其他地方传入,目的为了防止编译错误,但是这个变量在全局是可见
以下是混用事例代码:
功能脚本测试用例:test.cpp
#include
using namespace std;
extern int count;/*global variabal*/
#define newline "\n"
int auto_test()
{
auto f = 3.14;
auto z = new auto(9);
cout << "auto test:" << newline;
cout << typeid(f).name()<< newline;
cout << typeid(z).name()<< newline;
return 0;
}
int register_test()
{
register int a;
a = 10;
cout << "register test:"<< newline;
cout << a << newline;
return 0;
}
int static_test()
{
static int i = 5;
i++;
std::cout << "i :" << i << newline;
std::cout << "count : " << count << newline;
return 0;
}
这主函数的代码:main.cpp
#include
using namespace std;
extern void static_test();
extern void auto_test();
extern void register_test();
int count = 10;
int main()
{
while(count--)
{
static_test();
}
cout << "finally: " << count << "\n";
auto_test();
register_test()
return 0;
}
编译:
g++ test.cpp main.cpp -o main
运行:
./main
结果:
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
finally: -1
auto test:
d
Pi
register test:
10
12.运算符
算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和其他运算符
这些运算符合其他语言一致。
13.循环
控制语句:break,continue,goto
for(;;){}
#include
using namespace std;
#define newline "\n"
int func()
{
for(int i = 0;i<10;i++)
{
cout << i << newline;
}
return 0;
}
int main()
{
func();
}
14.判断
if 语句
if ...else 语句
swith 语句
条件运算符:Exp1 ? Exp2 : Exp3;
如果 Exp1 为真,则计算 Exp2 的值,结果即为整个 ? 表达式的值。如果 Exp1 为假,则计算 Exp3 的值,结果即为整个 ? 表达式的值。
#include
using namespace std;
#define newline "\n";
int func()
{
for(int i = 0;i<10;i++)
{
if (i>5)
{
cout << i << newline;
}else
{
cout << i << "<= 5" << newline;
}
}
int a = 10;
string b = a<20 ? "yes" : "no";
cout << "value = " << b << newline;
return 0;
}
int main()
{
func();
}
15.函数:
类似 int main(){} 这种结构
16.数字运算
#include
using namespace std;
#define newline "\n"
#include
int main(){
int a = 10;
float b = 3.14;
double c = 12.34;
float d = -5.2;
cout << "sin(a) = " << sin(a) << newline;
cout << "abs(b) = " << abs(b) << newline;
cout << "floor(b) = " << floor(b) << newline;
cout << "sqrt(a) = " << sqrt(a) << newline;
cout << "pow(a, 2) = " << pow(a, 2) << newline;
return 0;
}
17.随机数
在许多情况下,需要生成随机数。关于随机数生成器,有两个相关的函数。一个是 rand(),该函数只返回一个伪随机数。生成随机数之前必须先调用 srand() 函数。
#include
using namespace std;
#include
#define newline "\n"
int rand_max = 100;
int main()
{
srand(time(0));
// srand(rand_max);
cout << "random = " << rand() << newline;
cout << "random = " << rand() << newline;
return 0;
}
关于上面运行结果做如下解释:
1.如果单纯调用rand(),则表示默认的随机数种子就是srand(1),且随机数的序列是不变的,所以每次运行时,你得到的随机数是一样的。
2.如果先加随机数种子srand(rand_max),则改变了随机数的种子,但是每次运行时,你得到的随机数是一样的
3.如果加随机种子时一个随时都在变的种子srand(time(0)),则改变了随机数的种子,但是由于种子实时都在变的,所以每次你得到的随机数是变化的
18.数组用法
数组是通用前需要先定义
int arr[10] 表示数组长度为10,那你你就可以根据索引为其复制
#include
using namespace std;
int main()
{
int arr[10];
for(int i = 0;i<10;i++)
{
arr[i] = i;
}
cout << "array = " << arr[2] << "\n";
return 0;
}
多维数组定义方法如下:
type name[size1][size2]...[sizeN];
#include
using namespace std;
#define newline "\n"
int main()
{
//int arr[3][4]; //定义一个3x4二维数组
int arr[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
cout << "arr[2][2] = " << arr[2][2] << newline;
//int arr1[3][4];
int arr1[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
cout << "arr1[2][2] = " << arr1[2][2] << newline;
return 0;
}
要说明的是,数组初始化时,不能先定义了在初始化,先定义就只能对数组内的对象在进行赋值
int arr[3][4];
arr[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
也就是这种情况是不允许出现的
int arr2[3][4];
arr2[1][1] = 1;
只能这样
19.使用指针访问数组
#include
using namespace std;
#define newline "\n"
int main()
{
int arr[5] = {1,2,3,4,5};
int *p;
p = arr;
for(int i = 0; i<4; i++)
{
cout << "arr[p]= " << *(p+i) << newline;
}
return 0;
}
20.数组作为函数参数传递
#include
using namespace std;
#define newline "\n"
int func1(int *arr, int length)
{
for(int i = 0; i< length; i++)
{
cout << "func1 : " << arr[i] << newline;
}
}
int func2(int arr[],int length)
{
for(int i = 0; i< length; i++)
{
cout << "func2 : " << arr[i] << newline;
}
}
int main()
{
int arr[5] = {10, 20, 30, 40, 50};
int length = sizeof(arr)/sizeof(arr[0]);
//int length = end(arr) - begin(arr);
func1(arr,5);
func2(arr,5);
}
将数组作为参数传入函数,需要在函数外算出数组长度,传入还是函数中,因为函数内传入的数组的第一个对象的地址引用,即在函数内算不出实际数组对象的长度
21.对象地址引用
#include
using namespace std;
#define newline "\n"
int func(int a, int &b)
{
a += 1;
b += 1;
}
int main()
{
int a = 0;
int b = 0;
func(a, b);
cout << "a = " << a << newline;
cout << "b = " << b << newline;
}
这里a = 0, b = 1说明b并没有改变地址,并且改变了值,函数内外的b地址都没有发生变化
22.字符串
#include
#include
序号 |
函数 & 目的 |
1 |
strcpy(s1, s2); 复制字符串 s2 到字符串 s1。 |
2 |
strcat(s1, s2); 连接字符串 s2 到字符串 s1 的末尾。 |
3 |
strlen(s1); 返回字符串 s1 的长度。 |
4 |
strcmp(s1, s2); 如果 s1 和 s2 是相同的,则返回 0;如果 s1 |
5 |
strchr(s1, ch); 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。 |
6 |
strstr(s1, s2); 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。 |
23.指针
指针也是变量,也需要定义,只是指针的值是另一个对象的地址
int var = 20; // 实际变量的声明 int *ip; // 指针变量的声明 ip = &var; // 在指针变量中存储 var 的地址
空指针:int *ptr = NULL;
指针可以做运算:ptr++,ptr--,-,+
多级指针:多级寻址
指针与引用一起使用可以理解为全局变量
相关事例:
#include
using namespace std;
#define endline "\n"
int func1(unsigned long *a)
{
*a = 1;
}
int func2(unsigned long *a)
{
++*a;
}
int main()
{
unsigned long a;
func1(&a);
cout << "a = " << a << endline;
func2(&a);
cout << "a = " << a << endline;
}
24.引用
int& r = i; r是i的引用
#include
using namespace std;
int main ()
{
// 声明简单的变量
int i;
double d;
// 声明引用变量
int& r = i;
double& s = d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}
25.时间
序号 |
函数 & 描述 |
1 |
time_t time(time_t *time); 该函数返回系统的当前日历时间,自 1970 年 1 月 1 日以来经过的秒数。如果系统没有时间,则返回 .1。 |
2 |
char *ctime(const time_t *time); 该返回一个表示当地时间的字符串指针,字符串形式 day month year hours:minutes:seconds year\n\0。 |
3 |
struct tm *localtime(const time_t *time); 该函数返回一个指向表示本地时间的 tm 结构的指针。 |
4 |
clock_t clock(void); 该函数返回程序执行起(一般为程序的开头),处理器时钟所使用的时间。如果时间不可用,则返回 .1。 |
5 |
char * asctime ( const struct tm * time ); 该函数返回一个指向字符串的指针,字符串包含了 time 所指向结构中存储的信息,返回形式为:day month date hours:minutes:seconds year\n\0。 |
6 |
struct tm *gmtime(const time_t *time); 该函数返回一个指向 time 的指针,time 为 tm 结构,用协调世界时(UTC)也被称为格林尼治标准时间(GMT)表示。 |
7 |
time_t mktime(struct tm *time); 该函数返回日历时间,相当于 time 所指向结构中存储的时间。 |
8 |
double difftime ( time_t time2, time_t time1 ); 该函数返回 time1 和 time2 之间相差的秒数。 |
9 |
size_t strftime(); 该函数可用于格式化日期和时间为指定的格式。 |
前面的为类型,后面为函数名
#include
#include
using namespace std;
#define endline "\n"
int main()
{
time_t now1 = time(0); // seconds
cout << "time = " << now1 << endline;
char *now2 = ctime(&now1); //day month year hours:minutes:seconds year
cout << "ctime = " << now2 << endline;
struct tm *info = localtime(&now1) ;
cout << "localtime = " << info << endline;
clock_t start_clock,end_clock;
start_clock = clock();
for(int i = 0; i < 199999999; i++)
{
}
end_clock = clock();
double total_time = (end_clock-start_clock)/CLOCKS_PER_SEC;
cout << "clock = " << total_time << endline;
char *asc_time = asctime(info);
cout << "asctime = " << asc_time << endline;
}
参数传递的问题:
1.如果形参要求传指针,就必须传入指针或则引用
2.返回值根据定义,该定义为指针必须定义为指针
3.tm结构的数据可以获取具体方式如下:
info->tm_year 获取tm结构的年差
->表示指向类中的成员
26.输入输出
头文件
cout 输出流
cin 输入流
cerr 标准错误流
clog 标准日志流
#include
#include
using namespace std;
int main()
{
cout<
27.数据结构
我们可以定义自定义数据结构
#include
#include
#include
using namespace std;
#define endline "\n"
struct Human{
char name[20];
int age;
};
int team(struct Human object)
{
cout << object.age << " is " << object.name << "'s age" << endline;
}
int team1(struct Human *object)
{
cout << object->name << " 's age is " << object->age << endline;
}
int main()
{
Human xiaoming;
Human xiaofang;
strcpy(xiaoming.name, "xiaoming");
strcpy(xiaofang.name, "xiaofang");
xiaofang.age = 20;
xiaoming.age = 22;
team(xiaoming);
team(xiaofang);
team1(&xiaoming);
team1(&xiaofang);
}