C++语言学习

文章目录

教程

基本内置类型

类型 关键字
布尔型 bool
字符型 char
整型 int
浮点型 float
双浮点型 double
无类型 void
宽字符型 wchar_t

其中wchar_t
typedef short int wchar_t;

类型 范围
char 1个字节 -128到127 或者 0到255
unsigned char 1个字节 0到255
signed char 1个字节 -128到127
int 4个字节 -2147483648 到 214748y3647
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 8 个字节 -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 个宽字符

范例

#include<iostream>  
 
using namespace std;  
  
int main()  
{  
    cout << "type: \t\t" << "************size**************"<< endl;  
    cout << "bool: \t\t" << "所占字节数:" << sizeof(bool);  
    cout << "\t最大值:" << (numeric_limits<bool>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;  
    cout << "char: \t\t" << "所占字节数:" << sizeof(char);  
    cout << "\t最大值:" << (numeric_limits<char>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<char>::min)() << endl;  
    cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);  
    cout << "\t最大值:" << (numeric_limits<signed char>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<signed char>::min)() << endl;  
    cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);  
    cout << "\t最大值:" << (numeric_limits<unsigned char>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<unsigned char>::min)() << endl;  
    cout << "wchar_t: \t" << "所占字节数:" << sizeof(wchar_t);  
    cout << "\t最大值:" << (numeric_limits<wchar_t>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<wchar_t>::min)() << endl;  
    cout << "short: \t\t" << "所占字节数:" << sizeof(short);  
    cout << "\t最大值:" << (numeric_limits<short>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl;  
    cout << "int: \t\t" << "所占字节数:" << sizeof(int);  
    cout << "\t最大值:" << (numeric_limits<int>::max)();  
    cout << "\t最小值:" << (numeric_limits<int>::min)() << endl;  
    cout << "unsigned: \t" << "所占字节数:" << sizeof(unsigned);  
    cout << "\t最大值:" << (numeric_limits<unsigned>::max)();  
    cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl;  
    cout << "long: \t\t" << "所占字节数:" << sizeof(long);  
    cout << "\t最大值:" << (numeric_limits<long>::max)();  
    cout << "\t最小值:" << (numeric_limits<long>::min)() << endl;  
    cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long);  
    cout << "\t最大值:" << (numeric_limits<unsigned long>::max)();  
    cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl;  
    cout << "double: \t" << "所占字节数:" << sizeof(double);  
    cout << "\t最大值:" << (numeric_limits<double>::max)();  
    cout << "\t最小值:" << (numeric_limits<double>::min)() << endl;  
    cout << "long double: \t" << "所占字节数:" << sizeof(long double);  
    cout << "\t最大值:" << (numeric_limits<long double>::max)();  
    cout << "\t最小值:" << (numeric_limits<long double>::min)() << endl;  
    cout << "float: \t\t" << "所占字节数:" << sizeof(float);  
    cout << "\t最大值:" << (numeric_limits<float>::max)();  
    cout << "\t最小值:" << (numeric_limits<float>::min)() << endl;  
    cout << "size_t: \t" << "所占字节数:" << sizeof(size_t);  
    cout << "\t最大值:" << (numeric_limits<size_t>::max)();  
    cout << "\t最小值:" << (numeric_limits<size_t>::min)() << endl;  
    cout << "string: \t" << "所占字节数:" << sizeof(string) << endl;  
    // << "\t最大值:" << (numeric_limits<string>::max)() << "\t最小值:" << (numeric_limits<string>::min)() << endl;  
    cout << "type: \t\t" << "************size**************"<< endl;  
    return 0;  
}
type: 		************size**************
bool: 		所占字节数:1	最大值:1		最小值:0
char: 		所占字节数:1	最大值:		最小值:\200
signed char: 	所占字节数:1	最大值:		最小值:\200
unsigned char: 	所占字节数:1	最大值:\377		最小值:
wchar_t: 	所占字节数:4	最大值:2147483647		最小值:-2147483648
short: 		所占字节数:2	最大值:32767		最小值:-32768
int: 		所占字节数:4	最大值:2147483647	最小值:-2147483648
unsigned: 	所占字节数:4	最大值:4294967295	最小值:0
long: 		所占字节数:8	最大值:9223372036854775807	最小值:-9223372036854775808
unsigned long: 	所占字节数:8	最大值:18446744073709551615	最小值:0
double: 	所占字节数:8	最大值:1.79769e+308	最小值:2.22507e-308
long double: 	所占字节数:16	最大值:1.18973e+4932	最小值:3.3621e-4932
float: 		所占字节数:4	最大值:3.40282e+38	最小值:1.17549e-38
size_t: 	所占字节数:8	最大值:18446744073709551615	最小值:0
string: 	所占字节数:24
type: 		************size**************
Program ended with exit code: 0

枚举类型

enum 枚举名{ 
     标识符[=整型常数], 
     标识符[=整型常数], 
... 
    标识符[=整型常数]
} 枚举变量;

enum color {red, green, blue} c;
c = blue;

默认情况下,第一个名称的值为 0,第二个名称的值为 1,第三个名称的值为 2,以此类推。但是,您也可以给名称赋予一个特殊的值,只需要添加一个初始值即可。例如,在下面的枚举中,green 的值为 5。

enum color { red, green=5, blue };

C++变量类型

在这里插入图片描述

C++中的变量定义

type variable_list  = value

例如

int     i,j,k;
char    c,ch;
float   f,salary;
double  d;

extern int d=3,f=5;
int    d = 3, f = 5;
byte   z = 22;
char   x = 'x';

C++变量作用域

作用域是程序的一个区域,一般来说有三个地方可以定义变量

  • 在函数或一个代表代码块内部声明的变量,成为局部变量
  • 在函数参数的定义中声明的变量,成为形式参数
  • 在所有函数外部声明的变量,成为全局变量

局部变量

int main() 
{
	int a,b;
	int c;
	a = 10;
	b = 20;
}

全局变量

int g;
int main()
{
	int a = b;
	a = 10;
	b = 20;
	g = a + b;

初始化局部变量和全局变量

数据类型 初始化默认值
int 0
char ‘\0’
float 0
double 0
pointer NULL

C++常量

整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。

整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。

整数常量

212         // 合法的
215u        // 合法的
0xFeeL      // 合法的
078         // 非法的:8 不是八进制的数字
032UU       // 非法的:不能重复后缀
85         // 十进制
0213       // 八进制 
0x4b       // 十六进制 
30         // 整数 
30u        // 无符号整数 
30l        // 长整数 
30ul       // 无符号长整数

浮点常量

浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。

当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。当使用指数形式表示时, 必须包含小数点、指数,或同时包含两者。带符号的指数是用 e 或 E 引入的。

3.14159       // 合法的 
314159E-5L    // 合法的 
510E          // 非法的:不完整的指数
210f          // 非法的:没有小数或指数
.e55          // 非法的:缺少整数或分数

布尔常量

布尔常量共有两个,它们都是标准的 C++ 关键字:

true 值代表真。
false 值代表假。

字符常量

在这里插入图片描述

字符串常量

以下字符串相同

"hello, dear"

"hello, \

dear"

"hello, " "d" "ear"

定义常量

使用

#define
const

#deinfe预处理器

#define identifier value

#include <iostream>
using namespace std;

#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'

int mai() {
	int area;
	area = LENGTH * WIDTH;
	cout << area;
	cout << NEWLINE;
	return 0;
}

const关键字

const type variable = value;

#include <iostream>
using namespace std;
int main() 
{
	const int LENGHT = 10;
	const int WIDTH = 5;
	const char NEWLINE = '\n';

	area = LENGTH*WIDTH;
	cout << area;
	cout << NEWLIN;
	
	return 0;
}

C++ 修饰符类型

C++ 允许在 char、int 和 double 数据类型前放置修饰符。修饰符用于改变基本类型的含义,所以它更能满足各种情境的需求。

下面列出了数据类型修饰符:

  • signed
  • unsigned
  • long
  • short

修饰符 signed、unsigned、long 和 short 可应用于整型,signed 和 unsigned 可应用于字符型,long 可应用于双精度型。

修饰符 signed 和 unsigned 也可以作为 long 或 short 修饰符的前缀。例如:unsigned long int。

C++ 允许使用速记符号来声明无符号短整数或无符号长整数。您可以不写 int,只写单词 unsigned、short 或 unsigned、long,int 是隐含的。例如,下面的两个语句都声明了无符号整型变量。

unsinged x;
unsigned int y;
#include <iostream>
using namespace std;
int main() 
{
	short int i; //有符号短整数
	short unsigned int j; //无符号短整数
	
	j = 50000;
	i = j;
	cout << i << " " << j;
	return 0;
}

C++中的类型限定符

限定符 含义
const const类型的对象在程序执行期间不能被修改改变
const 修饰符volatile告诉编译器不需要优化volatile声明的变量,让程序可以直接从内存中读取变量。对于一般的变量编译器会对变量进行优化,将内存中的变量值放在寄存器中以加快读写效率
const 有restrict修饰的指针是唯一一种访问它所只想的对象的方式。只有C99增加了新的类型限定符restrict。

C++存储类

  • auto
  • register
  • static
  • extern
  • mutable
  • thread_local (C++11)

auto存储类

auto f=3.14; //double
auto s("hello"); // const char*
auto z = new auto(9); // int*
auto x1 = 5, x2 = 5.0, x3 = 'r'; //错误,必须是初始化为同一类型

register存储类

{
register int miles;
}

static 存储类

static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。

static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。

在 C++ 中,当 static 用在类数据成员上时,会导致仅有一个该成员的副本被类的所有对象共享。

#include <iostream>

// 函数声明
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为m "<<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’ 时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置。

当您有多个文件且定义了一个可以在其他文件中使用的全局变量或函数时,可以在其他文件中使用 extern 来得到已定义的变量或函数的引用。可以这么理解,extern 是用来在另一个文件中声明一个全局变量或函数。

main.cpp

#include <iostream>

int count;
extern void write_extern();

int main()
{
	count = 5;
	write_extern();
}

support.cpp

#include <iostream>
extener int count;

void write_extern(void)
{
	std::cout<<"Count is "<<count<<std::endl;
}
$g++ main.cpp support.cpp -o write
$./write
Count is 5

mutable存储类

mutable 说明符仅适用于类的对象,这将在本教程的最后进行讲解。它允许对象的成员替代常量。也就是说,mutable 成员可以通过 const 成员函数修改。

thread_local存储类

使用 thread_local 说明符声明的变量仅可在它在其上创建的线程上访问。 变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己的变量副本。

thread_local 说明符可以与 static 或 extern 合并。

可以将 thread_local 仅应用于数据声明和定义,thread_local 不能用于函数声明或定义。

thread_local int x;//命名空间下的全局变量

class X
{
	static thread_local std::string s;//类的static成员变量
}
static thread_local std::string X::s //X::s是需要定义的

void foo()
{
	thread_local std::vector<int> v;//本地变量
}

C++运算符

  • 算术元算符
  • 关系运算符
  • 逻辑元算符
  • 位运算符
  • 赋值运算符
  • 杂项运算符

算术运算符

在这里插入图片描述

#include <iostream>
using namespace std;
 
int main()
{
   int a = 21;
   int b = 10;
   int c;
 
   c = a + b;
   cout << "Line 1 - c 的值是 " << c << endl ;
   c = a - b;
   cout << "Line 2 - c 的值是 " << c << endl ;
   c = a * b;
   cout << "Line 3 - c 的值是 " << c << endl ;
   c = a / b;
   cout << "Line 4 - c 的值是 " << c << endl ;
   c = a % b;
   cout << "Line 5 - c 的值是 " << c << endl ;
 
   int d = 10;   //  测试自增、自减
   c = d++;
   cout << "Line 6 - c 的值是 " << c << endl ;
 
   d = 10;    // 重新赋值
   c = d--;
   cout << "Line 7 - c 的值是 " << c << endl ;
   return 0;
}
Line 1 - c 的值是 31
Line 2 - c 的值是 11
Line 3 - c 的值是 210
Line 4 - c 的值是 2
Line 5 - c 的值是 1
Line 6 - c 的值是 10
Line 7 - c 的值是 10

关系运算符

在这里插入图片描述

#include <iostream>
using namespace std;
 
int main()
{
   int a = 21;
   int b = 10;
   int c ;
 
   if( a == b )
   {
      cout << "Line 1 - a 等于 b" << endl ;
   }
   else
   {
      cout << "Line 1 - a 不等于 b" << endl ;
   }
   if ( a < b )
   {
      cout << "Line 2 - a 小于 b" << endl ;
   }
   else
   {
      cout << "Line 2 - a 不小于 b" << endl ;
   }
   if ( a > b )
   {
      cout << "Line 3 - a 大于 b" << endl ;
   }
   else
   {
      cout << "Line 3 - a 不大于 b" << endl ;
   }
   /* 改变 a 和 b 的值 */
   a = 5;
   b = 20;
   if ( a <= b )
   {
      cout << "Line 4 - a 小于或等于 b" << endl ;
   }
   if ( b >= a )
   {
      cout << "Line 5 - b 大于或等于 a" << endl ;
   }
   return 0;
}
Line 1 - a 不等于 b
Line 2 - a 不小于 b
Line 3 - a 大于 b
Line 4 - a 小于或等于 b
Line 5 - b 大于或等于 a

逻辑运算符

在这里插入图片描述

#include <iostream>
using namespace std;
 
int main()
{
   int a = 5;
   int b = 20;
   int c ;
 
   if ( a && b )
   {
      cout << "Line 1 - 条件为真"<< endl ;
   }
   if ( a || b )
   {
      cout << "Line 2 - 条件为真"<< endl ;
   }
   /* 改变 a 和 b 的值 */
   a = 0;
   b = 10;
   if ( a && b )
   {
      cout << "Line 3 - 条件为真"<< endl ;
   }
   else
   {
      cout << "Line 4 - 条件不为真"<< endl ;
   }
   if ( !(a && b) )
   {
      cout << "Line 5 - 条件为真"<< endl ;
   }
   return 0;
}
Line 1 - 条件为真
Line 2 - 条件为真
Line 4 - 条件不为真
Line 5 - 条件为真

位运算符

在这里插入图片描述
假设如果 A = 60,且 B = 13,现在以二进制格式表示,它们如下所示:

A = 0011 1100
B = 0000 1101


A&B = 0000 1100

A|B = 0011 1101

A^B = 0011 0001

~A = 1100 0011

下表显示了 C++ 支持的位运算符。假设变量 A 的值为 60,变量 B 的值为 13,则:

在这里插入图片描述

#include <iostream>
using namespace std;
 
int main()
{
   unsigned int a = 60;      // 60 = 0011 1100  
   unsigned int b = 13;      // 13 = 0000 1101
   int c = 0;           
 
   c = a & b;             // 12 = 0000 1100
   cout << "Line 1 - c 的值是 " << c << endl ;
 
   c = a | b;             // 61 = 0011 1101
   cout << "Line 2 - c 的值是 " << c << endl ;
 
   c = a ^ b;             // 49 = 0011 0001
   cout << "Line 3 - c 的值是 " << c << endl ;
 
   c = ~a;                // -61 = 1100 0011
   cout << "Line 4 - c 的值是 " << c << endl ;
 
   c = a << 2;            // 240 = 1111 0000
   cout << "Line 5 - c 的值是 " << c << endl ;
 
   c = a >> 2;            // 15 = 0000 1111
   cout << "Line 6 - c 的值是 " << c << endl ;
 
   return 0;
}
Line 1 - c 的值是 12
Line 2 - c 的值是 61
Line 3 - c 的值是 49
Line 4 - c 的值是 -61
Line 5 - c 的值是 240
Line 6 - c 的值是 15

赋值运算符

在这里插入图片描述

#include <iostream>
using namespace std;
 
int main()
{
   int a = 21;
   int c ;
 
   c =  a;
   cout << "Line 1 - =  运算符实例,c 的值 = : " <<c<< endl ;
 
   c +=  a;
   cout << "Line 2 - += 运算符实例,c 的值 = : " <<c<< endl ;
 
   c -=  a;
   cout << "Line 3 - -= 运算符实例,c 的值 = : " <<c<< endl ;
 
   c *=  a;
   cout << "Line 4 - *= 运算符实例,c 的值 = : " <<c<< endl ;
 
   c /=  a;
   cout << "Line 5 - /= 运算符实例,c 的值 = : " <<c<< endl ;
 
   c  = 200;
   c %=  a;
   cout << "Line 6 - %= 运算符实例,c 的值 = : " <<c<< endl ;
 
   c <<=  2;
   cout << "Line 7 - <<= 运算符实例,c 的值 = : " <<c<< endl ;
 
   c >>=  2;
   cout << "Line 8 - >>= 运算符实例,c 的值 = : " <<c<< endl ;
 
   c &=  2;
   cout << "Line 9 - &= 运算符实例,c 的值 = : " <<c<< endl ;
 
   c ^=  2;
   cout << "Line 10 - ^= 运算符实例,c 的值 = : " <<c<< endl ;
 
   c |=  2;
   cout << "Line 11 - |= 运算符实例,c 的值 = : " <<c<< endl ;
 
   return 0;
}
Line 1 - =  运算符实例,c 的值 = 21
Line 2 - += 运算符实例,c 的值 = 42
Line 3 - -= 运算符实例,c 的值 = 21
Line 4 - *= 运算符实例,c 的值 = 441
Line 5 - /= 运算符实例,c 的值 = 21
Line 6 - %= 运算符实例,c 的值 = 11
Line 7 - <<= 运算符实例,c 的值 = 44
Line 8 - >>= 运算符实例,c 的值 = 11
Line 9 - &= 运算符实例,c 的值 = 2
Line 10 - ^= 运算符实例,c 的值 = 0
Line 11 - |= 运算符实例,c 的值 = 2

杂项运算符

在这里插入图片描述

C++中的元算符优先级

在这里插入图片描述

#include <iostream>
using namespace std;
 
int main()
{
   int a = 20;
   int b = 10;
   int c = 15;
   int d = 5;
   int e;
 
   e = (a + b) * c / d;      // ( 30 * 15 ) / 5
   cout << "(a + b) * c / d 的值是 " << e << endl ;
 
   e = ((a + b) * c) / d;    // (30 * 15 ) / 5
   cout << "((a + b) * c) / d 的值是 " << e << endl ;
 
   e = (a + b) * (c / d);   // (30) * (15/5)
   cout << "(a + b) * (c / d) 的值是 " << e << endl ;
 
   e = a + (b * c) / d;     //  20 + (150/5)
   cout << "a + (b * c) / d 的值是 " << e << endl ;
  
   return 0;
}
(a + b) * c / d 的值是 90
((a + b) * c) / d 的值是 90
(a + b) * (c / d) 的值是 90
a + (b * c) / d 的值是 50

C++循环

在这里插入图片描述

循环类型

  • while 循环
  • for 循环
  • do…while循环
  • 嵌套循环

循环控制语句

  • break语句
  • continue语句
  • goto语句

无限循环

#include <iostream>
using namespace std;
 
int main ()
{
 
   for( ; ; )
   {
      printf("This loop will run forever.\n");
   }

	while(true){}
 
   return 0;
}

C++判断

在这里插入图片描述

判断语句

  • if语句
  • if…else语句
  • 嵌套if语句
  • switch语句-必须是一个常量或字 面量
  • 嵌套switch语句
#include <iostream>
using namespace std;

int main()
{
	// 局部变量声明
	char grade = 'D';
	switch(grade)
	{
		case 'A':
			cout << "greet!"<<endl;
			break;
		case 'B‘:
		case 'C':
			cout<<"well down"<<endl;
			break;
		case 'D':
			cout<<"pass"<<endl;
			break;
		case 'F':
			break;
		default:
			cout<<"invalide"<<grade<<endl;

		return 0;
	}
}

?:元算符

Exp1 ? Exp2 : Exp3;

C++函数

定义函数

return_type function_name(parameter list)
{
	body of the function
}
  • 返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。
  • 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
  • 参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
  • 函数主体:函数主体包含一组定义函数执行任务的语句。
// 函数返回两个数中较大的那个数
int max(int num1, int num2)
{
	int result;
	if(num1 > num2)
	{
		result = num1;
	} 
	else 
	{
		result = num2;
	}
	return result;
}

函数声明

return_type function_name(parameter list);

int mai(int num1, int num2);

参数名称是并不重要
int max(int, int);

调用函数

#include <iostream>
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 <iostream>
using namespace std;
 
// 函数声明
void swap(int x, int y);
 
int main ()
{
   // 局部变量声明
   int a = 100;
   int b = 200;
 
   cout << "交换前,a 的值:" << a << endl;
   cout << "交换前,b 的值:" << b << endl;
 
   // 调用函数来交换值
   swap(a, b);
 
   cout << "交换后,a 的值:" << a << endl;
   cout << "交换后,b 的值:" << b << endl;
 
   return 0;
}
交换前,a 的值: 100
交换前,b 的值: 200
交换后,a 的值: 100
交换后,b 的值: 200
  • 指针调用
    向函数传递参数的指针调用方法,把参数的地址复制给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
#include <iostream>
using namespace std;

// 函数声明
void swap(int *x, int *y);

int main ()
{
   // 局部变量声明
   int a = 100;
   int b = 200;
 
   cout << "交换前,a 的值:" << a << endl;
   cout << "交换前,b 的值:" << b << endl;

   /* 调用函数来交换值
    * &a 表示指向 a 的指针,即变量 a 的地址 
    * &b 表示指向 b 的指针,即变量 b 的地址 
    */
   swap(&a, &b);

   cout << "交换后,a 的值:" << a << endl;
   cout << "交换后,b 的值:" << b << endl;
 
   return 0;
}

// 函数定义
void swap(int *x, int *y)
{
   int temp;
   temp = *x;    /* 保存地址 x 的值 */
   *x = *y;        /* 把 y 赋值给 x */
   *y = temp;    /* 把 x 赋值给 y */
  
   return;
}
交换前,a 的值: 100
交换前,b 的值: 200
交换后,a 的值: 200
交换后,b 的值: 100
  • 引用调用
    向函数传递参数的引用调用方法,把引用的地址复制给形式参数。
#include <iostream>
using namespace std;
 
// 函数声明
void swap(int &x, int &y);
 
int main ()
{
   // 局部变量声明
   int a = 100;
   int b = 200;
 
   cout << "交换前,a 的值:" << a << endl;
   cout << "交换前,b 的值:" << b << endl;
 
   /* 调用函数来交换值 */
   swap(a, b);
 
   cout << "交换后,a 的值:" << a << endl;
   cout << "交换后,b 的值:" << b << endl;
 
   return 0;
}

// 函数定义
void swap(int &x, int &y)
{
   int temp;
   temp = x; /* 保存地址 x 的值 */
   x = y;    /* 把 y 赋值给 x */
   y = temp; /* 把 x 赋值给 y  */
  
   return;
}
交换前,a 的值: 100
交换前,b 的值: 200
交换后,a 的值: 200
交换后,b 的值: 100

参数的默认值

当您定义一个函数,您可以为参数列表中后边的每一个参数指定默认值。当调用函数时,如果实际参数的值留空,则使用这个默认值。

这是通过在函数定义中使用赋值运算符来为参数赋值的。调用函数时,如果未传递参数的值,则会使用默认值,如果指定了值,则会忽略默认值,使用传递的值。请看下面的实例:

#include <iostream>
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 vlaue is :"<<result<<endl;
	//再次调用函数
	result = sum(a);
	cout<<"Total value is:"<<result<<endl;
	return 0;
}
Total value is :300
Total value is :120

Lambda函数与表达式(C++11)

Lambda表达式把函数看作对象。Lambda表达式可以像对象一样使用,比如可以将它们赋值变量和作为参数传递,还可以像函数一样对其求值

[capture](parameters)->return-type(body)

例如

[](int x, int y){return x < y;}

如果没有返回值可以表示为

[capture](parameters){body}

例如
···
[]{ ++global_x; }
···

[](int x, int y) -> int { int z = x + y; return z + x; }

C++数字

C++定义数字

#include <iostream>
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++数学运算

函数 描述
double cos(double); 该函数返回弧度角(double 型)的余弦。
double sin(double); 该函数返回弧度角(double 型)的正弦。
double tan(double); 该函数返回弧度角(double 型)的正切。
double log(double); 该函数返回参数的自然对数。
double pow(double, double); 假设第一个参数为 x,第二个参数为 y,则该函数返回 x 的 y 次方。
double hypot(double, double); 该函数返回两个参数的平方总和的平方根,也就是说,参数为一个直角三角形的两个直角边,函数会返回斜边的长度。
double sqrt(double); 该函数返回参数的平方根。
int abs(int); 该函数返回整数的绝对值。
double fabs(double); 该函数返回任意一个浮点数的绝对值。
double floor(double); 该函数返回一个小于或等于传入参数的最大整数。
#include <iostream>
#include <cmath>
using namespace std;
 
int main ()
{
   // 数字定义
   short  s = 10;
   int    i = -1000;
   long   l = 100000;
   float  f = 230.47;
   double d = 200.374;
 
   // 数学运算
   cout << "sin(d) :" << sin(d) << endl;
   cout << "abs(i)  :" << abs(i) << endl;
   cout << "floor(d) :" << floor(d) << endl;
   cout << "sqrt(f) :" << sqrt(f) << endl;
   cout << "pow( d, 2) :" << pow(d, 2) << endl;
 
   return 0;
}

C++随机数

在许多情况下,需要生成随机数。关于随机数生成器,有两个相关的函数。一个是 rand(),该函数只返回一个伪随机数。生成随机数之前必须先调用 srand() 函数。

下面是一个关于生成随机数的简单实例。实例中使用了 time() 函数来获取系统时间的秒数,通过调用 rand() 函数来生成随机数:

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main() 
{
	int i,j;
	//设置种子
	srand((unsigned)time(NULL));
	/*生成10个随机数*/
	for(i =0; i<10;i++) {
		//生成实际的随机数
		j = rand();
		cout<<"随机数"<<j<<endl;
	}
	return 0;
}
随机数: 1748144778
随机数: 630873888
随机数: 2134540646
随机数: 219404170
随机数: 902129458
随机数: 920445370
随机数: 1319072661
随机数: 257938873
随机数: 1256201101
随机数: 580322989

C++数组

声明数组

type arrayName [arraysize];

double balance[10];

初始化数组

double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
balance[4]=50.0;

在这里插入图片描述

访问数组元素

double salary = balance[9];

#include <iostream>
using namespace std;

#include <iomanip>
using std::setw;

int main()
{
	int n[10];//n是包含10个整数的数组
	//初始化数组
	for (int i=0; i<10; i++)
	{
		n[i]=i+100;//设置元素为i+100
	}
	//输出数组中每个元素的值
	for(int j=0;j<10;j++)
	{
		cout<<set2(7)<<j<<set2(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

C++中数组详解

  • 多维数组
  • 指向数组的指针
  • 传递数组给函数
  • 从函数返回数组
#include <iostream>
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
// 要生成和返回随机数的函数
int * getRandom( )
{
  static int  r[10];
 
  // 设置种子
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)
  {
    r[i] = rand();
    cout << r[i] << endl;
  }
 
  return r;
}
 
// 要调用上面定义函数的主函数
int main ()
{
   // 一个指向整数的指针
   int *p;
 
   p = getRandom();
   for ( int i = 0; i < 10; i++ )
   {
       cout << "*(p + " << i << ") : ";
       cout << *(p + i) << endl;
   }
 
   return 0;
}
624723190
1468735695
807113585
976495677
613357504
1377296355
1530315259
1778906708
1820354158
667126415
*(p + 0) : 624723190
*(p + 1) : 1468735695
*(p + 2) : 807113585
*(p + 3) : 976495677
*(p + 4) : 613357504
*(p + 5) : 1377296355
*(p + 6) : 1530315259
*(p + 7) : 1778906708
*(p + 8) : 1820354158
*(p + 9) : 667126415

C++字符串

  • C风格字符串
  • C++引入的string类类型

C风格字符串

char greeting[6]={‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\0’};
依据数组初始化规则,也可以这样写:
char greeting[] = “Hello”;

在这里插入图片描述

#include <iostream>
 
using namespace std;
 
int main ()
{
   char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
 
   cout << "Greeting message: ";
   cout << greeting << endl;
 
   return 0;
}
Greeting message: Hello
函数 目的
strcpy(s1, s2) 赋值字符串s2到字符串s1
strcat(s1,s2) 连接字符串s2到字符串s1的末尾
strlen(s1) 返回字符串s1的长度
strcmp(s1, s2) 如果s1和s2是相同的,怎返回0;如果s1<s2则返回值小于0;如果s1>s2则返回值大于0
strchr(s1, ch); 返回一个指针,指向字符串s1中字符ch的第一次出现的位置
strstr(s1, s2) 返回一个指针,指向s1中字符串s2的第一次出现的位置
#include <iostream>
#include <cstring>
 
using namespace std;
 
int main ()
{
   char str1[11] = "Hello";
   char str2[11] = "World";
   char str3[11];
   int  len ;
 
   // 复制 str1 到 str3
   strcpy( str3, str1);
   cout << "strcpy( str3, str1) : " << str3 << endl;
 
   // 连接 str1 和 str2
   strcat( str1, str2);
   cout << "strcat( str1, str2): " << str1 << endl;
 
   // 连接后,str1 的总长度
   len = strlen(str1);
   cout << "strlen(str1) : " << len << endl;
 
   return 0;
}
strcpy( str3, str1) : Hello
strcat( str1, str2): HelloWorld
strlen(str1) : 10

C++中的string类

#include <iostream>
#include <string>
 
using namespace std;
 
int main ()
{
   string str1 = "Hello";
   string str2 = "World";
   string str3;
   int  len ;
 
   // 复制 str1 到 str3
   str3 = str1;
   cout << "str3 : " << str3 << endl;
 
   // 连接 str1 和 str2
   str3 = str1 + str2;
   cout << "str1 + str2 : " << str3 << endl;
 
   // 连接后,str3 的总长度
   len = str3.size();
   cout << "str3.size() :  " << len << endl;
 
   return 0;
}
str3 : Hello
str1 + str2 : HelloWorld
str3.size() :  10

C++指针

https://www.runoob.com/cplusplus/cpp-pointers.html

#include <iostream>
 
using namespace std;
 
int main ()
{
   int  var1;
   char var2[10];
 
   cout << "var1 变量的地址: ";
   cout << &var1 << endl;
 
   cout << "var2 变量的地址: ";
   cout << &var2 << endl;
 
   return 0;
}
var1 变量的地址: 0xbfebd5c0
var2 变量的地址: 0xbfebd5b6

什么是指针

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明

type *var-name;

int    *ip;    /* 一个整型的指针 */
double *dp;    /* 一个 double 型的指针 */
float  *fp;    /* 一个浮点型的指针 */
char   *ch;    /* 一个字符型的指针 */

C++中使用指针

使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。

#include <iostream>
using namespace std;
int main()
{
	int var = 20; //实际变量的声明
	int *ip;  //指针变量的声明
	ip = &var; //在指针变量中储存var的地址
	
	cout<< "Value of var variable:";
	cout << var << endl;
	
	//输出在指针变量中存储的地址
	cout<<"Address stored in ip variable:";
	cout<<ip<<endl;
	//访问指针中地址的值
	cout<<"Value of *ip variable";
	cout<<*ip<<endl;
	return 0;
}
Value of var variable: 20
Address stored in ip variable: 0xbfc601ac
Value of *ip variable: 20

C++指针详解

  • C++Null指针
    C++支持空指针,NULL指针是一个定义在标准库中的值为零的常量
  • C++指针的算术运算
    可以对指针进行四种算术运算:++、–、+、-
  • C++指针vs数组
    指针和数组之间有着密切的关系
  • C++指针数组
    可以定义用来存储指针的数组
  • C++指向指针的指针
    C++允许指向指针的指针
  • C++传递指针给函数
    通过引用或地址传递参数,使传递的参数在调用函数中被改变。
  • C++从函数返回指针
    C++允许函数返回指针到局部变量、静态变量和动态内存分配

C++Null指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋值一个NULL值是一个良好的编程习惯。称为空指针。

#include <iostream>
using namespace std;
int main()
{
	int *ptr = NULL;
	cout<<"ptr 的值是”<<ptr;
	return 0;
}
ptr的值是0
if(ptr) /*如果ptr非空,则完成*/
if(!ptr) /*如果ptr为空,则完成*/

C++指针的算术运算

ptr++

在执行完上述的运算之后,ptr将指向位置1004,因为ptr每增加一次,它都将指向下一个证书位置,即当前位置往后移4个字节。这个运算会在不影响内存位置中实际值的情况下,移动指针到下一个内存位置。如果ptr指向一个地址为1000的字符,上面的运算会导致指向位置1001, 因为洗一个字符位置是在1001.

  • 递增一个指针
#include <iostream>

using namespace std;
const int MAX = 3;

int main()
{	
	int var[MAX] = {10, 100, 200};
	int *ptr;
	
	//指针中的数组地址
	ptr = var;
	for(int i=0; i<MAX; i++)
	{
		cout << "Address of var["<<i<<"] =";
		cout << ptr << endl;

		cout << "Value of var["<<i<<"] =";
		cout<<*ptr<<endl;
		//移动到下一个位置
		ptr++;
	}
	return 0;
}
Address of var[0] = 0xbfa088b0
Value of var[0] = 10
Address of var[1] = 0xbfa088b4
Value of var[1] = 100
Address of var[2] = 0xbfa088b8
Value of var[2] = 200
  • 递减一个指针
#include <iostream>

using namespace std;
const int MAX = 3;

int main()
{
	int var[MAX] = {10, 100, 200};
	int *ptr;

	//指针中最后一个元素的地址
	ptr = &var[MAX - 1];
	for (int i = MAX; i > 0; i--){
		cout << "Address of var["<<i<<"]=";
		cout << ptr <<endl;
		cout << "Value of var[" <<i<<"]=";
		cout<<*ptr<<endl;
		//移动到下一个位置
		ptr--;
	}
	return 0;
}

Address of var[3] = 0xbfdb70f8
Value of var[3] = 200
Address of var[2] = 0xbfdb70f4
Value of var[2] = 100
Address of var[1] = 0xbfdb70f0
Value of var[1] = 10
  • 指针的比较
#include <iostream>

using namespace std;
const int MAX = 3;

int main() 
{
	int var[MAX] = {10, 100, 200};
	int *ptr;
	
	// 指针中第一个元素的的izhi
	ptr = var;
	int i = 0;
	while(ptr <= &var[MAX - 1])
	{
		cout << "Address of var["<<i<<"]=";
		cout<<ptr<<endl;
		
		cout<<"Value of var["<<i<<"]=";
		cout<<*ptr<<endll;

		//指向一个位置
		ptr++;
		i++;
	}
	return 0;
}


Address of var[0] = 0xbfce42d0
Value of var[0] = 10
Address of var[1] = 0xbfce42d4
Value of var[1] = 100
Address of var[2] = 0xbfce42d8
Value of var[2] = 200

C++指针vs数组

指针和数组是密切相关的。事实上,指针和数组在很多情况下是可以互换的。

#include <iostream>

using namespace std;
const int MAX = 3;
int main() 
{
	int var[MAX] = {10, 100, 200};
	int *ptr;
	//指针中的数组地址
	ptr = var;
	for(int i = 0; i < MAX; i++) {
		cout<<"var["<<i<<"]的内存地址为";
		cout<<ptr<<endl;
		cout<<"var["<<i<<"]的值为“;
		cout<<*ptr<<endl;
		ptr++;
	}
	return 0;
}
var[0]的内存地址为 0x7fff59707adc
var[0] 的值为 10
var[1]的内存地址为 0x7fff59707ae0
var[1] 的值为 100
var[2]的内存地址为 0x7fff59707ae4
var[2] 的值为 200

然而,指针和数组并不是完全互换的。

#include <iostream>
using namesapce std;
const int MAX = 3;

int main(){
	int var[MAX] = {10, 100, 200};
	
	for(int i=0; i<MAX; i++) {
		*var = i;//这是正确的语法
		var++;//这是不正确的语法
	}
	return 0;
}

把指针运算符 * 应用到 var 上是完全可以的,但修改 var 的值是非法的。这是因为 var 是一个指向数组开头的常量,不能作为左值。

由于一个数组名对应一个指针常量,只要不改变数组的值,仍然可以用指针形式的表达式。例如,下面是一个有效的语句,把 var[2] 赋值为 500:

*(var + 2) = 500;

C++指针数组

用到了一个由3个整数组成的数组

#include <iostream>
using namespace std;
const int MAX = 3;
int main() 
{
	int var[MAX] = {10, 100, 200};
	for(int i = 0; i < MAX, i++) 
	{
		cout<<"Value of var["<<i<<"]=";
		cout<<var[i]<<endl;
	}
	return 0;
}
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200

可能有一种情况,我们想要让数组存储指向 int 或 char 或其他数据类型的指针。下面是一个指向整数的指针数组的声明:

int *ptr[MAX];

在这里,把 ptr 声明为一个数组,由 MAX 个整数指针组成。因此,ptr 中的每个元素,都是一个指向 int 值的指针。下面的实例用到了三个整数,它们将存储在一个指针数组中,如下所示:

#include <iostream>
using namespace std;
const int MAX = 3;

int main() 
{
	int var[MAX] = {10, 100, 200};
	int *ptr[MAX];
	for(int i=0; i<MAX;I++)
	{
		ptr[i] = &var[i]; //赋值为整数的地址
	}
	for(int i=0;i<MAX;i++)
	{
		cout << "Value of var["<<i<<"]=";
		cout<<*ptr[i]<<endl;
	}
}
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200

您也可以用一个指向字符的指针数组来存储一个字符串列表,如下:

#include <iostream>

using namespace std;
const int MAX = 4;

int main() 
{
	const char *names[MAX] = {
		"Zara Ali",
		"Hina Ali",
		"Nuha Ali",
		"Sara Ali"
	};
	for(int i=0; i<MAX; i++) 
	{
		cout<<"Value of names["<<i<<"]=";
		cout<<names[i]<<endl;
	}
	return 0;
}
Value of names[0] = Zara Ali
Value of names[1] = Hina Ali
Value of names[2] = Nuha Ali
Value of names[3] = Sara Ali

C++指向指针的指针(多级间接寻址)

在这里插入图片描述

int **var;
#include <iostream>
using namespace std;
int main()
{
	int var;
	int *ptr;
	int **pptr;
	var = 3000;
	//获取var的地址
	ptr = &var;
	//使用运算符&获取ptr的值
	pptr=&ptr;
	//使用pptr获取值
	cout<<"var 值为"<<var<<endl;
	cout<<"*ptr值为:"<<*ptr<<endl;
	cout<<"**pptr值为"<<**pptr<<endl;
}
var 值为 :3000
*ptr 值为:3000
**pptr 值为:3000

C++传递指针给函数

C++ 允许您传递指针给函数,只需要简单地声明函数参数为指针类型即可。

#include <iostream>
#include <ctime>

using namespace std;
void getSeconds(unsigned long *par);

int main()
{
	unsigned long sec;
	getSeconds(&sec);
	//输出实际值
	cout<<"Number of seconds:"<<sec<<endl;
	return 0;
}

void getSeconds(unsigned long *par)
{
	//获取当前的描述
	*par = time(NULL);
	return;
}

Number of seconds :1294450468

能接受指针作为参数的函数,也能接受数组作为参数,如下所示:

#include <iostream>
using namespace std;

//函数声明
double getAverage(int *arr, int size);

int main()
{
	//带有5个元素的整形数组
	int balance[6]={1000, 2, 3, 17, 50};
	double avg;
	//传递一个指向数组的指针作为参数
	avg = getAverage(balance, 5);
	return 0;
}

double getAverage(int *arr, int size)
{
	int i,sum=0;
	double avg;
	for(i=0; i<size; ++i) 
	{
		sum += arr[i];
	}
	avg = double(sum) / size;
	return avg;
}

Average value is: 214.4

C++从函数返回指针

#include <iostream>
#include <ctime>
#include <cstdlib>
 
using namespace std;
 
// 要生成和返回随机数的函数
int * getRandom( )
{
  static int  r[10];
 
  // 设置种子
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)
  {
    r[i] = rand();
    cout << r[i] << endl;
  }
 
  return r;
}
 
// 要调用上面定义函数的主函数
int main ()
{
   // 一个指向整数的指针
   int *p;
 
   p = getRandom();
   for ( int i = 0; i < 10; i++ )
   {
       cout << "*(p + " << i << ") : ";
       cout << *(p + i) << endl;
   }
 
   return 0;
}
624723190
1468735695
807113585
976495677
613357504
1377296355
1530315259
1778906708
1820354158
667126415
*(p + 0) : 624723190
*(p + 1) : 1468735695
*(p + 2) : 807113585
*(p + 3) : 976495677
*(p + 4) : 613357504
*(p + 5) : 1377296355
*(p + 6) : 1530315259
*(p + 7) : 1778906708
*(p + 8) : 1820354158
*(p + 9) : 667126415

C++引用

引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

C++引用vs指针

引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化某个变量,就可以使用该引用名称或变量名称来指向变量。

  • 不存在空引用。引用必须连接到一块儿合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须创建时初始化。指针可以在任何时间被初始化。

C++中创建引用

#include <iostream>
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;
}
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7

把引用作为参数

#include <iostream>
using namespace std;

//函数声明
void swap(int& x, int&y);

int mian()
{
	//局部变量声明
	int a = 100;
	int b = 200;
	
	cout<<"交换前,a的值"<<a<<endl;
	cout<<"交换前,b的值"<<b<<endl;
	swap(a,b);
	cout<<"交换前,a的值"<<a<<endl;
	cout<<"交换前,b的值"<<b<<endl;
	return 0;
}

//函数定义
void swap(int &x, int $y)
{
	int temp;
	temp = x;
	x = y;
	y = temp;
	return;
}

交换前,a 的值: 100
交换前,b 的值: 200
交换后,a 的值: 200
交换后,b 的值: 100

把引用作为返回值

#include <iostream>
using namespace std;

double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};

double& setValues(int i)
{
	return vals[i]; //返回第i个元素的引用
}

//要调用上面定义函数的主函数
int main()
{
	cout<<"改变的值"<<endl;
	for(int i=0; i<5; i++)
	{
		cout<<"vals["<<i<<"]";
		cout<<vals[i]<<endl;
		setValues(1)=20.23;//改变第2个元素
		setValues(3)=70.8;//改变第4个元素
		cout<<"改变后的值<<endl;
		for(int i=0; i<5; i++)
		{
			cout<<"vals["<<i<<"] =";
			cout<<vals[i]<<endl;
		}
		return 0;
	}
}



改变前的值
vals[0] = 10.1
vals[1] = 12.6
vals[2] = 33.1
vals[3] = 24.1
vals[4] = 50
改变后的值
vals[0] = 10.1
vals[1] = 20.23
vals[2] = 33.1
vals[3] = 70.8
vals[4] = 50

当返回一个引用时,要注意被引用的对象不能超出作用域。所以返回一个对局部变量的引用是不合法的,但是,可以返回一个对静态变量的引用。

int& func()
{
	int q;
	// ! return q;//在编译的时候发生错误s
	static int x;
	return x;//安全,x在函数作用域外依然是有效的
}

C++日期&时间

C++标准库没有提供所谓的日期类型,C++继承了C语言用于日期和时间操作的结构和函数。为了使用日期和时间相关的函数和结构。需要在C++程序中引用头文件。
有四个与时间相关的类型:clock_t、time_t、size_t、tm。类型clock_t、size和time_t能够把系统时间和日期表示为某种整数。
结构类型tm把日期和时间以C结构的形式保存,tm结构的定义如下:

struct tm {
	int tm_sec; //秒,正常范围从0到59,但允许至61
	int tm_min; //分,范围从0到59
	int tm_hour; //小时,范围从0到23
	int tm_mday; //一月中的第几天,范围从1到31
	int tm_mon; //月,范围从0到11
	int tm_year; //自1900年起的年数
	int tm_wday;//一周中的第几天,范围从0到5,从星期日算起
	int tm_yday; //一年中的第几天,范围从0到365,从1月1日算起
	int tm_isdst; //夏令时
}

下面是C/C++中关于日期和时间的重要函数。所有这些函数都是C/C++标准库的组成部分,您可以在C++标准库中查看一下各个函数的细节。

函数 描述
time_t time(time_t *time); 该函数返回系统的当前日历时间,自1970年1月1日以来经过的秒数。如果系统没有时间,则返回1
char *ctime(const time_t *time); 该返回一个表示当地时间的字符串指针,字符串形式 day month year hours:minutes:seconds year\n\0
struct tm *localtime(const time_t *time); 该函数返回一个指向本地时间的tm结构指针
clock_t clock(void) 该函数返回程序执行起(一般为程序的开头),处理器时钟所使用的时间。如果时间不可用,则返回1
char * asctime(const struct tm*time); 该函数返回一个指向字符串的指针,字符串包含了time所指向结构中存储的信息,返回形式为:day month date hours:minutes:seconds year\n\0
struct *gmtime(const time_t *time); 该函数返回一个指向 time 的指针,time 为 tm 结构,用协调世界时(UTC)也被称为格林尼治标准时间(GMT)表示。
time_t mktime(struct tm *tie); 该函数返回日历时间,相当于 time 所指向结构中存储的时间。
double difftime(time_t time2, time_t time1) 该函数返回 time1 和 time2 之间相差的秒数。
size_t strftime(); 该函数可用于格式化日期和时间为指定的格式。

当前日期和时间

#include <iostream>
#include <ctime>
using namespace std;

int main()
{
	//基于当前系统的当前日期/时间
	time_t now = time(0);
	//把now转换为字符串形式
	char* dt = ctime(&now);
	cout<<"本地日期和时间:"<<dt<<endl;
	//把now转换为tm结构
	tm *gmtm = gmtime(&now);
	dt = asctime(gmtm);
	cout<<"UTC日期和时间:"<<dt<<endl;
	
}


本地日期和时间:Sat Jan  8 20:07:41 2011

UTC 日期和时间:Sun Jan  9 03:07:41 2011

使用结构tm格式化时间

tm 结构在 C/C++ 中处理日期和时间相关的操作时,显得尤为重要。tm 结构以 C 结构的形式保存日期和时间。大多数与时间相关的函数都使用了 tm 结构。下面的实例使用了 tm 结构和各种与日期和时间相关的函数。

在练习使用结构之前,需要对 C 结构有基本的了解,并懂得如何使用箭头 -> 运算符来访问结构成员。

#include <iostream>
#include <ctime>

using namespace std;
int main() 
{
	//基于当前系统的当前日期/时间
	time_t now = time(0);
	cout<<"1970到目前经过秒数"<<now<<endl;
	tm *ltm = localtime(&now);
	//输出tm结构的各个组成部分
	cout<<"年:"<<1900+ltm->tm_year<<endl;
	cout<<"月:"<<1+ltm->tm_mon<<endl;
	cout<<"日:"<<ltm->tm_mday<<endl;
	cout<<"时间:"<<ltm->tm_hour<<":";
	cout<<ltm->tm_min<<":";
	cout<<ltm->tm_sec<<endl;
}

1970 到目前时间:1503564157
年: 2017
月: 8
日: 24
时间: 16:42:37

C++基本的输入输出

C++ 的 I/O 发生在流中,流是字节序列。如果字节流是从设备(如键盘、磁盘驱动器、网络连接等)流向内存,这叫做输入操作。如果字节流是从内存流向设备(如显示屏、打印机、磁盘驱动器、网络连接等),这叫做输出操作。

头文件 函数和描述
该文件定义了cin、cout、cerr和clog对象,分别对应于标准输入流、标准输出流、非缓冲区标准错误流和缓冲标准错误流
该文件通过所谓的参数化的流操纵器(比如setw和setprecision),来声明对执行标准化I/O有用的服务
该文件为用户控制的文件处理声明服务。我们将在文件和流的相关章节讨论它的细节

标准输出流(cout)

预定义的对象 cout 是 iostream 类的一个实例。cout 对象"连接"到标准输出设备,通常是显示屏。cout 是与流插入运算符 << 结合使用的,如下所示:

#include <iostream>
using namespace std;
int main()
{
	char str[] = "Hello C++";
	cout<<"Value of str is :"<<str<<endl;
}
Value of str is : Hello C++

C++ 编译器根据要输出变量的数据类型,选择合适的流插入运算符来显示值。<< 运算符被重载来输出内置类型(整型、浮点型、double 型、字符串和指针)的数据项。

流插入运算符 << 在一个语句中可以多次使用,如上面实例中所示,endl 用于在行末添加一个换行符。

标准输入流(cin)

预定义的对象 cin 是 iostream 类的一个实例。cin 对象附属到标准输入设备,通常是键盘。cin 是与流提取运算符 >> 结合使用的,如下所示:

#include <iostream>
using namespace std;
int main() 
{
	char name[50];
	cout<<"清输入您的名称:";
	cin>>name;
	cout<<"您的名称是:"<<name<<endl;
}
请输入您的名称: cplusplus
您的名称是: cplusplus

以下情况相等

cin>>name>>age;

cin>>name;
cin>>age;

标准错误流(cerr)

预定义的对象 cerr 是 iostream 类的一个实例。cerr 对象附属到标准错误设备,通常也是显示屏,但是 cerr 对象是非缓冲的,且每个流插入到 cerr 都会立即输出。

cerr 也是与流插入运算符 << 结合使用的,如下所示:

#include <iostream>
using namespace std;
int main()
{
	char str[] = "Unable to read...“;
	cerr<<"Error message:"<<str<<endl;
}
Error message : Unable to read....

标准日志流(clog)

预定义的对象 clog 是 iostream 类的一个实例。clog 对象附属到标准错误设备,通常也是显示屏,但是 clog 对象是缓冲的。这意味着每个流插入到 clog 都会先存储在缓冲在,直到缓冲填满或者缓冲区刷新时才会输出。

clog 也是与流插入运算符 << 结合使用的,如下所示:

#include <iostream>
using namespace std;
int main()
{
	char str[] = "Unable to read...";
	clog<<"Error message:"<<str<<endl;
}
Error message : Unable to read....

输入输出流中的函数(模板)

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    cout<<setiosflags(ios::left|ios::showpoint);  // 设左对齐,以一般实数方式显示
    cout.precision(5);       // 设置除小数点外有五位有效数字 
    cout<<123.456789<<endl;
    cout.width(10);          // 设置显示域宽10 
    cout.fill('*');          // 在显示区域空白处用*填充
    cout<<resetiosflags(ios::left);  // 清除状态左对齐
    cout<<setiosflags(ios::right);   // 设置右对齐
    cout<<123.456789<<endl;
    cout<<setiosflags(ios::left|ios::fixed);    // 设左对齐,以固定小数位显示
    cout.precision(3);    // 设置实数显示三位小数
    cout<<999.123456<<endl; 
    cout<<resetiosflags(ios::left|ios::fixed);  //清除状态左对齐和定点格式
    cout<<setiosflags(ios::left|ios::scientific);    //设置左对齐,以科学技术法显示 
    cout.precision(3);   //设置保留三位小数
    cout<<123.45678<<endl;
    return 0; 
}
123.46
****123.46
999.123
1.235e+02

其中 cout.setf 跟 setiosflags 一样,cout.precision 跟 setprecision 一样,cout.unsetf 跟 resetiosflags 一样。

setiosflags(ios::fixed) 固定的浮点显示 
setiosflags(ios::scientific) 指数表示 
setiosflags(ios::left) 左对齐 
setiosflags(ios::right) 右对齐 
setiosflags(ios::skipws 忽略前导空白 
setiosflags(ios::uppercase) 16进制数大写输出 
setiosflags(ios::lowercase) 16进制小写输出 
setiosflags(ios::showpoint) 强制显示小数点 
setiosflags(ios::showpos) 强制显示符号 

cout.setf 常见的标志:

标志 功能
boolalpha 可以使用单词”true”和”false”进行输入/输出的布尔值.
oct 用八进制格式显示数值.
dec 用十进制格式显示数值.
hex 用十六进制格式显示数值.
left 输出调整为左对齐.
right 输出调整为右对齐.
scientific 用科学记数法显示浮点数.
fixed 用正常的记数方法显示浮点数(与科学计数法相对应).
showbase 输出时显示所有数值的基数.
showpoint 显示小数点和额外的零,即使不需要.
showpos 在非负数值前面显示”+(正号)”.
skipws 当从一个流进行读取时,跳过空白字符(spaces, tabs, newlines).
unitbuf 在每次插入以后,清空缓冲区.
internal 将填充字符回到符号和数值之间.
uppercase 以大写的形式显示科学记数法中的”e”和十六进制格式的”x”.

iostream 中定义的操作符:

操作符 描述 输入 输出
boolalpha 启用boolalpha标志
dec 启用dec标志
endl 输出换行标示,并清空缓冲区
ends 输出空字符
fixed 启用fixed标志
flush 清空流
hex 启用 hex 标志
internal 启用 internal 标志
left 启用 left 标志
noboolalpha 关闭boolalpha 标志
noshowbase 关闭showbase 标志
noshowpoint 关闭showpoint 标志
noshowpos 关闭showpos 标志
noskipws 关闭skipws 标志
nounitbuf 关闭unitbuf 标志
nouppercase 关闭uppercase 标志
oct 启用 oct 标志
right 启用 right 标志
scientific 启用 scientific 标志
showbase 启用 showbase 标志
showpoint 启用 showpoint 标志
showpos 启用 showpos 标志
skipws 启用 skipws 标志
unitbuf 启用 unitbuf 标志
uppercase 启用 uppercase 标志
ws 跳过所有前导空白字符

iomanip 中定义的操作符:

操作符 描述 输入 输出
resetiosflags(long f) 关闭被指定为f的标志
setbase(int base) 设置数值的基本数为base
setfill(int ch) 设置填充字符为ch
setiosflags(long f) 启用指定为f的标志
setprecision(int p) 设置数值的精度(四舍五入)
setw(int w) 设置域宽度为w

C++数据结构

定义结构

struct type_name{
	member_type1 member_name1;
	member_type2 member_name2;
	member_type3 member_nam3;
	.
	.
} object_names;
struct Books
{
	char title[50];
	char author[50];
	char subject[100];
	int book_id;
} book;

访问结构成员

使用成员访问运算符(.)

#include <iostream>
#include <cstring>
using namespace std;

//声明一个结构体类型 Books
struct Books
{
	char title[50];
	char author[50];
	char subject[100];
	int book_id;
};

int main()
{
	Books Book1; //定义结构体类型Books的变量Book1
	Books Book2; //定义结构体类Books的变量Book2

	//Book1详述
	strcpy(Book1.title, "C++教程");
	strcpy(Book1.author, "Runoob");
	strcpy(Book1.subject, "编程语言");
	Book1.book_id = 12345;

	//Book2详述
	strcpy(Book1.title, "CSS 教程");
	strcpy(Book1.author, "Runoob");
	strcpy(Book1.subject, "前端技术");
	Book1.book_id = 12346;

	//输出Book1信息
	cout<<"第一本书标题:"<<Book1.title<<endl;
	cout<<"第一本作者:"<<Book1.author<<endl;
	cout<<"第一本书类目:"<<Book1.subject<<endl;
	cout<<"第一本书ID"<<Book1.book_id<<endl;
	
	//输出Book2信息
	cout<<"第二本书标题:"<<Book2.title<<endl;
	cout<<"第二本作者:"<<Book2.author<<endl;
	cout<<"第二本书类目:"<<Book2.subject<<endl;
	cout<<"第二本书ID"<<Book2.book_id<<endl;
	return 0;
}




第一本书标题 : C++ 教程
第一本书作者 : Runoob
第一本书类目 : 编程语言
第一本书 ID : 12345
第二本书标题 : CSS 教程
第二本书作者 : Runoob
第二本书类目 : 前端技术
第二本书 ID : 12346

结构作为函数参数

#include <iostream>
#include <cstring>

using namespace std;
void printBook(struct Books book);

//声明一个结构体类型Books
struct Books
{
	char title[50];
	char author author[50];
	char subject[100];
	int book_id;
};

int main()
{
	Books Book1;
	Books Book2;

    // Book1 详述
   strcpy( Book1.title, "C++ 教程");
   strcpy( Book1.author, "Runoob"); 
   strcpy( Book1.subject, "编程语言");
   Book1.book_id = 12345;
 
   // Book2 详述
   strcpy( Book2.title, "CSS 教程");
   strcpy( Book2.author, "Runoob");
   strcpy( Book2.subject, "前端技术");
   Book2.book_id = 12346;

	//输出Book1信息
	printBook(Book1);
	//输出Book2信息
	printBook(Book2);
	return 0;
}

void printBook(struct Books book)
{
   cout << "书标题 : " << book.title <<endl;
   cout << "书作者 : " << book.author <<endl;
   cout << "书类目 : " << book.subject <<endl;
   cout << "书 ID : " << book.book_id <<endl;
}
书标题 : C++ 教程
书作者 : Runoob
书类目 : 编程语言
书 ID : 12345
书标题 : CSS 教程
书作者 : Runoob
书类目 : 前端技术
书 ID : 12346

指向结构的指针

定义指向结构的指针,方式与定义指向其他类型变量的指针相似,如下所示:
struct Books *struct_pointer;

可以在上述定义的指针变量中存储结构变量的地址。
struct_pointer = &Book1;

struct_pointer->title;

#include <iostream>
#include <cstring>
 
using namespace std;
void printBook( struct Books *book );
 
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};
 
int main( )
{
   Books Book1;        // 定义结构体类型 Books 的变量 Book1
   Books Book2;        // 定义结构体类型 Books 的变量 Book2
 
    // Book1 详述
   strcpy( Book1.title, "C++ 教程");
   strcpy( Book1.author, "Runoob"); 
   strcpy( Book1.subject, "编程语言");
   Book1.book_id = 12345;
 
   // Book2 详述
   strcpy( Book2.title, "CSS 教程");
   strcpy( Book2.author, "Runoob");
   strcpy( Book2.subject, "前端技术");
   Book2.book_id = 12346;
 
   // 通过传 Book1 的地址来输出 Book1 信息
   printBook( &Book1 );
 
   // 通过传 Book2 的地址来输出 Book2 信息
   printBook( &Book2 );
 
   return 0;
}
// 该函数以结构指针作为参数
void printBook( struct Books *book )
{
   cout << "书标题  : " << book->title <<endl;
   cout << "书作者 : " << book->author <<endl;
   cout << "书类目 : " << book->subject <<endl;
   cout << "书 ID : " << book->book_id <<endl;
}
书标题  : C++ 教程
书作者 : Runoob
书类目 : 编程语言
书 ID : 12345
书标题  : CSS 教程
书作者 : Runoob
书类目 : 前端技术
书 ID : 12346

typedef关键字

下面是一种更简单的定义结构的方式,您可以为创建的类型取一个”别名“。例如:

typedef struct Books
{
	char title[50];
	char author[50];
	char subject[100];
	int book_id;
} Books;

Books Book1, Book2; 

可以使用typedef关键字来定义非结构类型
typedef long int *pint32;
pint32 x,y,z;

资料

C++

发布了167 篇原创文章 · 获赞 62 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/AdrianAndroid/article/details/104426293