C++基础

VS快捷键

Ctrl +或- 跳转到上次鼠标焦点位置

Ctrl K F 按住Ctrl 然后按K 然后按F

Ctrl J 代码提示

变量

声明方式:数据类型 变量名 = 变量初始值

#include <iostream>
using namespace std;

int main()
{
    int a = 1;
    char b = 'b'; 
}

常量

#define 宏常量

声明方式:#define 常量名 常量值 通常在文件上方定义

#include <iostream>
using namespace std;

#define day 7

int main()
{
    cout << "一周有" << day <<"天" << endl;
}

const修饰的变量

声明方式:const 数据类型 变量名 = 变量值

#include <iostream>
using namespace std;

int main()
{
    const int day = 7;
    cout << "一周有" << day <<"天" << endl;
}

命名规则

  • 标识符不能是关键字
  • 标识符只能有字母,数字,下划线
  • 第一个字符必须为字母或下划线
  • 区分大小写

数据类型

整型

  • short 2字节
  • int 4字节
  • long windows 4字节 Linux32位 4字节 Linux64位 8字节
  • long long 8字节

sizeof关键字

  • 用来获取数据类型所占用内存大小
  • 语法: sizeof( 数据类型 / 变量 )
#include <iostream>
using namespace std;

int main()
{
	int a = 1;
	long b = 1;
	long long c = 1;
	cout << "int类型占用:" << sizeof(int) << endl;
	cout << "int变量占用:" << sizeof(a) << endl;
	cout << "long类型占用:" << sizeof(long) << endl;
	cout << "long变量占用:" << sizeof(b) << endl;
	cout << "long long类型占用:" << sizeof(long long) << endl;
	cout << "long long变量占用:" << sizeof(c) << endl;
}

输出结果(我使用的是windows 所以long类型也是4字节大小):

int类型占用:4
int变量占用:4
long类型占用:4
long变量占用:4
long long类型占用:8
long long变量占用:8

浮点型

  • double 8字节 有效数字范围15-16位
  • float 4字节 有效数字范围7位

需要注意的一点是:当我们声明一个float类型的带小数的变量时,编辑器会默认认为是double类型,准确指出类型需要在变量值最后加F

#include <iostream>
using namespace std;

int main()
{
	float a = 1.1F;
	float b = 1.1;
}

上面两种都可

字符型

语法: char c='a'

  • 字符类型只能使用单引号,而不是双引号
  • 只能是单个字符,不能是字符串
  • c/c++中字符类型只占用1字节
  • 字符类型并不是把字符本身放到内存中存储,而是转换为对应的ASCll码存放
#include <iostream>
using namespace std;

int main()
{
	char a = 'h';
	char b = 'e';
	cout << "变量a:" << a << endl;
	cout << "变量b:" << b << endl;
}

输出char类型变量的ascll码

强转为int类型输出即可

#include <iostream>
using namespace std;

int main()
{
	char a = 'h';
	char b = 'e';
	cout << "变量a:" << (int)a << endl;
	cout << "变量b:" << (int)b << endl;
}

转义字符

就写几个常用的

  • \n 换号
  • \t 一个table的位置
  • \\ 代表一个\

字符串类型

C风格字符串

声明方式: char 变量名[] = "字符串值"

#include <iostream>
using namespace std;

int main()
{
    char s[] = "hello world";
    cout << s << endl;
}

C++风格字符串

声明方式:string 变量名="字符串值"

如果使用不了string 需要导入头文件

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

int main()
{
    string s = "hello world";
    cout << s << endl;
}

Bool类型

表示真和假,只有两个值

  • false 0
  • true 1

bool类型只占用一个字节大小

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

int main()
{
    bool b = true;
    cout << b << endl;
}

数据的输入

用于获取键盘的输入

关键词:cin 语法: cin>>变量

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

int main()
{
    int a = 1;
    cin >> a;
    cout << a << endl;
}

运算符

  1. 算数运算符 处理四则运算
  2. 赋值运算符 将表达式赋值给变量
  3. 比较运算符 表达式的比较并返回一个bool值
  4. 逻辑运算符 用于根据表达式的值返回true或false

算数运算符

运算符 术语 示例 结果
+ 正号 +3 3
负号 -3 -3
+ 加号 10+5 15
减号 10-5 5
* 乘号 10*5 50
/ 除号 10/5 2
% 取模(取余) 10%3 1
++ 前置自增 a=2;b=++a; a=3;b=3;
++ 后置自增 a=2;b=a++; a=3;b=2;
前置自减 a=2;b=–a; a=1;b=1;
后置自减 a=2;b=a–; a=1,b=2

tips: 两数相除,除数不能为0

两数取余,第二个数也不能为0;

两个小数是不能做取余操作

int main()
{
    int a = 2;
    int b = a++;
    //其他操作也基本类似,就不粘代码了
    cout << a << endl;
    cout << b << endl;
}

赋值运算符

运算符 术语 示例 结果
= 赋值 a=2; a=2;
+= 加等于 a=2; a+=1; a=3;
-= 减等于 a=2;a-=1; a=1;
*= 乘等于 a=2;a*=2; a=4;
/= 除等于 a=4;a/=2; a=2;
%= 模等于 a=3;a%=2; a=1;
#include <iostream>
#include <string>
using namespace std;

int main()
{
    int a = 1;
    a += 1;
//    a = a + 1;  等同于这段代码  其他操作类似
    cout << a << endl;
}

比较运算符

运算符 术语 示例 结果
== 相等于 1==1 1 (true)
!= 不等于 1!=1 0 (false)
< 小于 1<1 0 (false)
<= 小于等于 1<=1 1 (true)
> 大于 1>1 0 (false)
>= 大于等于 1>=1 1 (true)
#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << (1<=1) << endl;
}

逻辑运算符

运算符 术语 示例 结果
! 非(取反) !a 如果a为假,则!a为真 反之亦然
&& 与 (并且) a&&b 如果ab都为真,则结果为真,其中一个为假,则整体为假
|| 或 (或者) a||b 只要其中一个为真,则结果为真,都为假则结果为假
#include <iostream>
#include <string>
using namespace std;

int main()
{
    int a = 10;
    cout << !a << endl;
    /*
    结果为0 因为逻辑运算符会把变量当成bool类型来操作,bool中只有0和非0
    那么10作为非0的数值被当成true,取反为false, 而false的int类型数值为0
    所以结果为0
    */
    
    cout << !!a << endl;
    /*
    结果为1  原因如上,当第一个!走完后结果已经为0了,而bool值只有0和非0 
    非零默认值是1,所以两次取反后结果为1
    */
    
    //加几个!没有限制,可以无限加
  
}
#include <iostream>
#include <string>
using namespace std;

int main()
{
	int a = 10;
	int b = 0;
	cout << (a && b) << endl;
    /*
    结果为0 (false)
    */
}
#include <iostream>
#include <string>
using namespace std;

int main()
{
	int a = 10;
	int b = 0;
	cout << (a|| b) << endl;
    /*
    结果为1 (true)
    */
}

程序流程结构

选择结构

if

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

int main(){

	int a = 10;
	int b = 0;
	if (a) {
		cout << "a" << endl;
	}
	else if (b){
		cout <<"b" << endl;
	}
	else {
		cout << "else" << endl;
	}
}

三目运算符

语法:条件?为true返回的:否则返回的

例如a=1;b=2;

a>b?a:b

a大于b吗?是的返回a,否则返回b

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

int main() {

	int a = 10;
	int b = 0;
	int c = a > b ? a : b;
	cout << c << endl;
    /*
		结果10
    */
}
#include <iostream>
#include <string>
using namespace std;

int main() {

	int a = 10;
	int b = 0;
    //返回变量并赋值
	( a > b ? a : b)=50;
	cout << a << endl;
	cout << b << endl;
    /*
    结果a=50
    b=0;
    */
}

不仅可以返回变量,也可以在三目中进行赋值操作等

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

int main() {

	int a = 10;
	int b = 0;
	int c;
	a > b ? c = 10 : c = 20;
	cout << c << endl;
    //结果c=10;
}

switch

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

int main() {
	
	char a = 's';
	switch (a)
	{
	case 's':
		cout << "s" << endl;
		break;
	case 'h':
		cout << "h" << endl;
		break;
	default:
		cout << "default" << endl;
		break;
	}
    //结果 s
}
#include <iostream>
#include <string>
using namespace std;

int main() {
	
	int a = 3;

	switch (a)
	{
	case 1:
		cout << "1" << endl;
		break;
	case 2:
		cout << "2" << endl;
		break;
	default:
		cout << "default" << endl;
		break;
	}
    //结果 default
}

tips : 如果一个case没有break,则会继续执行下面的case直到结束 default也会执行

循环结构

while

语法:while(条件){循环语句}

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

int main() {
	
	int a = 1;
	while (a < 10) {
		cout << ++a << endl;
	}
    //一直循环到10结束
}

do..while

语法: do{循环语句} while(条件)

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

int main() {

	bool eat = false;
	do	{
		cout << "吃个汉堡,还要吃吗?"<< endl;
		cin >> eat;
	} while (eat);
    /*
    结果:
    吃个汉堡,还要吃吗?
    1
    吃个汉堡,还要吃吗?
    1
    吃个汉堡,还要吃吗?
    0
    程序结束
    */
}

for

语法:for(起始变量;循环条件;循环结束执行代码){循环语句}

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

int main() {
	char my_name[] = "jame";
    
	for (int i = 0; i < sizeof(my_name); i++)
	{
		cout << my_name[i] << endl;
	}
    
    /*
    sizeof可以获取到占用的内存大小,就是char的个数 一个char占一字节 那么sizeof(my_name)结果就是4
    每次循环输出具体下标的内容就可以完成遍历了
    结果:
    j
    a
    m
    e
    
    */
}

小练习:打印乘法表

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

int main() {

	for (int i = 1; i <= 9; i++) 
	{
		for (int j = 1; j <= i; j++) 
		{
			cout << i << "*" << j << "=" << (i*j) << " ";
		}
		cout << "\n";
	}
}
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

跳转语句

语法: break

使用的时机:

  • 在switch中,终止case并跳出switch
  • 循环中跳出当前循环

上面的乘法表中使用

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

int main() {

	for (int i = 1; i <= 9; i++) 
	{
		for (int j = 1; j <= i; j++) 
		{
			if (j == i) 
			{
				break;
			}
			cout << i << "*" << j << "=" << (i*j) << " ";
		}
		cout << "\n";
	}
}

2*1=2
3*1=3 3*2=6
4*1=4 4*2=8 4*3=12
5*1=5 5*2=10 5*3=15 5*4=20
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72

当i==j的时候直接跳出循环了,所以看不到1乘1,2乘2这样类似的输出

contiune

当在循环中出现contiune时,直接进行下次循环

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

int main() {

	for (int i = 1; i <= 9; i++) 
	{
		if (i % 2 == 0) 
		{
			continue;
		}
		cout << i;
	}
}
//结果133579

goto

无条件跳转

语法:goto 标记

如果标记的位置存在,则执行到goto时会直接跳转到标记的位置

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

int main() {

	for (int i = 1; i <= 9; i++)
	{
		if (i == 8)
		{
			goto END;
		}
		cout << i;

	}
END:
	cout << "结束啦";
}

不光是往下面跳,还能往上跳

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

int main() {
	int b = 0;
	RESTART:
	if (b > 0) {
		cout << "b!" << endl;
	}
	for (int i = 1; i <= 9; i++)
	{
		if (i == 8 && b == 0)
		{
			b = 10;
			goto RESTART;
		}
		cout << i ;
	}
}

/*
	结果
    1234567b!
    123456789
*/

使用goto向上面跳时一定要注意结束的判断,避免死循环

数组

特点1:同个数组内的每个元素都相同类型的

特点2:数组是内存中一块连续内存地址组成的

定义数组

int main() {
    int a[10];
    int b[10] = { 1,2,3 };  //如果标记长度为10,但是只初始化3个值,那么剩下的默认值都是0
    int c[] = { 1,2,3 };
}

三种定义数组的方式

访问数组

int main() {
	int a[10];

	a[1] = 1;
	a[2] = 100;
	
}

数组名用途

  1. 可以获取整个数组在内存中的长度
  2. 可以获取内存中数组的首地址
#include <iostream>
#include <string>
using namespace std;

int main() {
	
	int a[10] = { 1,2,3 };

	cout << "数组占用总大小" << sizeof(a) << endl;
	cout << "每个元素占用大小" << sizeof(a[0]) << endl;
	cout << "数组中有多少个元素" << sizeof(a)/sizeof(a[0]) << endl;
}
数组占用总大小40
每个元素占用大小4
数组中有多少个元素10

tips: 数组中有多少个元素 这里使用a[0] 而不是其他a[1],a[2]…的原因 首先数组的特性1,每个元素都是相同类型的,也就是所有的元素大小都是一样的,使用那个都可以

那么也可以使用a[1],a[2]… 但是需要注意的是下标不能超过定义的最大长度

int main() {
	
	int a[10] = { 1,2,3 };

	cout << "数组首地址"<< a << endl;
	cout << "数组第一个元素的首地址"<< &a[0] << endl;
	
}

tips: &在变量前是获取元素的地址

二维数组

定义:

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

int main() {
	
	int a[3][3]; //声明一个三行三列的数组
	int b[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; //声明三行三列,同时赋初始值
	int c[3][3] = { 1,2,3,4,5,6,7,8,9 }; //声明三行三列 同时全部赋值 三个为一行
	int d[][3] = { 1,2,3,4,5,6 }; //声明一个两行三列 同时赋值
}

数组名称

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

int main() {
	
	int b[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; //声明三行三列,同时赋初始值
	
	cout << "二维数组首地址:" << b << endl;
	cout << "二维数组一行大小:" << sizeof(b[0]) << endl;
	cout << "二维数组元素大小:" << sizeof(b[0][0]) << endl;


}

二维数组遍历


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

int main() {

	int b[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; //声明三行三列,同时赋初始值

	for (int i = 0; i < (sizeof(b)/sizeof(b[0])); i++) 
	{
		for (int j = 0; j < (sizeof(b[0])/sizeof(b[0][0])); j++)
		{
			cout << b[i][j];
		}
	}

}

函数(方法)

一个函数包含以下内容:

  1. 返回值类型
  2. 函数名称
  3. 参数列表
  4. 函数体
  5. return

//返回值类型和函数名称,参数为空
int main() {
	//函数体

	cout << "hello world";
    //return值
	return 0;

}

函数的调用

int sum(int number1, int number2) {
	return number1 + number2;
}


int main() {
	cout << sum(1,2);
	return 0;
}

tips: C++和JAVA不一样,被调用的函数必须在调用函数的方法前声明

值传递

值传递是指当实参传递给形参后,当形参发生改变,实参并不会发生变化

int test(int number1) {
	number1 += 1;
	return 0 ;
}

int main() {
	int a = 1;
	test(a);
	cout << a;
	return 0;
}

当调用完test函数后a的值输出还是1,或者我们输出number1a的地址,也会发现不同,说明test的参数只是值传递

int test(int number1) 
{

	number1 += 1;
	cout << &number1 << endl;
	return 0 ;
}


int main() 
{
	int a = 1;
	test(a);
	cout << &a<<endl;
	return 0;
}
/*
000000FF976FF550
000000FF976FF574
*/

函数常见样式

  • 有参有返

    int sum(int a,int b) 
    {
    	return a+b;
    }
    
  • 有参无返

    void print_number(int number) 
    {
    	cout << number;
    }
    
  • 无参有返

    int get_one()
    {
        return 1;
    }
    
  • 无参无返

    void print_hello(){
        cout << "hello";
    }
    

函数的声明

在函数的开始篇有个tips 说使用的被调用的函数必须声明在调用的函数前,而函数声明就可以让被调用的函数声明在调用的函数之后

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

int main() {
	int a = 1;
	print(a);
	return 0;
}

void print(int a) {
	cout << a;
}

我们这么写编译是没有问题,但是当运行起来后就会报错:print找不到标识符

调换个位置就可以正常运行


void print(int a) {
	cout << a;
}

int main() {
	int a = 1;
	print(a);
	return 0;
}

而函数的声明就是提前声明我有这个函数

语法:返回类型 函数名(参数); 一个函数可以被声明多次,但是只能定义一次

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

void print(int a);  //提前声明存在print函数

int main() {
	int a = 1;
	print(a);
	return 0;
}

void print(int a) {
	cout << a;
}

函数分文件编写

将相同功能的函数单独放在一个文件中,使结构更加清晰

  1. 创建后缀为.h 的头文件
  2. 创建后缀为.cpp的源文件
  3. 在头文件中写函数声明
  4. 在源文件中写函数实现

myHead.h

#include <iostream>
using namespace std;


void print(int a);

myHead.cpp

#include "myHead.h";

void print(int a) {
	cout << a;
}

主文件

#include "myHead.h";

int main() {
	int a = 1;
	print(a);
	return 0;
}

我们在.h头文件中引入了iostream 也使用了std 那么只要导入myHead.h文件的都可以使用

咋说呢,有点像java的接口?哈哈哈

指针

指针的作用:可以通过指针直接访问内存

  • 内存编号从0开始,一般为16进制数字表示
  • 可以使用指针变量保存地址

指针的定义和使用

语法:数据类型* 变量名

int main() {
	int a = 1;
	int* a_pointer = &a;//将a的地址存放到指针中
	*a_pointer = 100;//将100赋值给指针指向的地址中 指针前加*代表解引用  找到指针指向内存中的数据
	cout << a << endl;
	cout << "a的地址" << &a<<endl;
	cout << "a指针的数据"<<a_pointer << endl;
}

指针占用的内存

int main() {
	cout << sizeof(int *) << endl;
	cout << sizeof(short *) << endl;
	cout << sizeof(float *) << endl;
	cout << sizeof(double *) << endl;
	cout << sizeof(long *) << endl;
	cout << sizeof(long long  *) << endl;
}

32位中都是4字节 64位中都是8字节

空指针和野指针

空指针:指针变量指向内存中编号为0的空间

用途: 初始化指针

注意: 空指针的内存是不可访问的

int main() {
	int* a = NULL;
	cout << *a << endl;
    //*a = 100;  或者这段代码
}
//都会报一个访问权限的异常

野指针:指针变量指向非法的内存空间

int main() {
	int* a = (int*)0x10000; //(int * 强制转换为指针类型)
	*a = 100;
}
//也会报一个访问权限的异常

tips: 空指针和野指针都不是我们申请的空间,因此不要访问

const修饰指针

const有三种情况

  1. 修饰指针:常量指针
  2. 修饰常量:指针常量
  3. 即修饰指针,又修饰常量

常量指针

int main() {
	int a = 10;
	int b = 20;
	/*
	* 常量指针
	* 指针指向的值不可修改,但是可以修改指向
	*/
	const int* p = &a;
	//*p = 10;   修改指向的值 错误
	p = &b;//修改指向 可以
}

指针常量

int main() {
	int a = 10;
	int b = 20;
	/*
	* 指针常量
	* 指针指向的值不可修改,但是可以修改指向
	*/
	int* const p = &a;
	*p = 10;   //修改指向的值 可以
	//p = &b;//修改指向 错误

}

即修饰指针,又修饰常量

int main() {
	int a = 10;
	int b = 20;
	/*
	* 即修饰指针,也修饰常量
	* 指针指向的值不可修改,但是可以修改指向
	*/
	const int* const p = &a;
	//*p = 10;   //修改指向的值 错误
	//p = &b;//修改指向 错误
}

指针和数组

利用指针访数组中的元素

int main() {
	int a[5] = { 1,2,3,4,5 };
	int* p = a;
	cout << *p;
	p++;
	cout << *p;
}

tips: 指针类型++ 加的是sizeof(指针类型) 的值, int加4字节正好是下个元素的地址 然后*p解引用取值也就是下个元素的值

指针和函数

利用指针作为函数的参数,从而修改实参的值,也就是常说的值传递和引用传递,而当使用指针作为参数传递时,就是引用传递

void add(int* num1) {
	(*num1)++; 
}
int main() {
	int a = 10;
	add(&a);
	cout << a;
}

当执行完后a的值为11

tips: 括号标明是先去获取指针指向的值,然后自增1,如果不加可能以为是指针值++然后取值

指针数组和函数

小练习 冒泡

int* arr接收数组的地址,可以当做数组使用

void golugolu(int* arr ,int lenght) 
{
	for (int i = 0; i < lenght; i++)
	{
		for (int j = 0; j < lenght - i- 1; j++) 
		{
			if (arr[j] > arr[j + 1]) 
			{
				int temp = arr[j];
				arr[j]=arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	
	}


}

int main() {

	int a[5] = { 2,3,1,4,5 };
	golugolu(a,5);

	for (int i = 0; i < 5; i++)
	{
		cout << a[i];
	}
}

结构体

结构体属于用户自定义的数据类型,允许用户存储不同的数据类型

语法: struct 结构体名 {结构体成员列表}

tpis: 注意! 结构体结束}后面需要加一个;结尾

通过结构体创建变量的方式有三种:

  1. struct 结构体名 变量名
  2. struct 结构体名 变量名={成员1值,成员2值}
  3. 定义结构体时同时设置变量

方式1

//定义结构体
struct Student
{
	//声明结构体中的成员
	string name;
	int score;
	int age;
};

int main()
{
	struct Student student;  //struct可以省略
	student.age = 10;
	student.name = "张三";
	student.score = 90;
	cout << student.age << endl;
}

方式2

#include <iostream>
#include <string> //如果string类型报错则导入该头文件
using namespace std;

//定义结构体
struct Student
{
	//声明结构体中的成员
	string name;
	int score;
	int age;
};

int main()
{
	struct Student student = { "张三",90,18 }; //struct可以省略
	
	cout << student.name << endl;
}

类似于有参构造,每个变量的顺序就是在结构体中声明的顺序

方式3

//定义结构体
struct Student
{
	//声明结构体中的成员
	string name;
	int score;
	int age;
} oldStudnet;  //标明一个结构体

int main()
{
    //可以使用上面两种来进行填充数据
	oldStudnet = { "we",1,1 };
	oldStudnet.age = 199;
	cout << oldStudnet.name << endl;
    cout << oldStudnet.age << endl;
}

结构体数组

语法:struct 结构体名 数组名[个数]={{},{},{},...{}


//定义结构体
struct Student
{
	//声明结构体中的成员
	string name;
	int score;
	int age;
};

int main()
{
	struct Student arr[3] =
	{
		{"张三",1,1},
		{"李四",2,2},
		{"王五",3,3}
	};

	//整个数组长度除以每个元素长度获取到多少个元素
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
        //在循环中就可以将arr[i]当成具体的struct
		arr[i].age = 10;
		cout << arr[i].name;
	}
}

结构体指针

语法: 可以通过-> 来访问结构体中的属性


//定义结构体
struct Student
{
	//声明结构体中的成员
	string name;
	int score;
	int age;
};

int main()
{
	//创建结构体变量
	struct Student studnet = { "张三",1,1 };
	//创建指针变量,同时指向student变量
	struct Student* p = &studnet;
	//使用-> 操作符操作变量age
	p->age = 100;
	cout << p->age;
}

结构体嵌套结构体

struct Dog {
	string name;
	int age;
};

//定义结构体
struct Student
{
	//声明结构体中的成员
	string name;
	int score;
	int age;
	struct Dog dog;
};

int main()
{
	struct Dog dog = { "旺财",4 };
    //将dog设置到student中
	struct Student student = { "小明",90,10,dog };

	//先获取学生的指针
	struct Student* student_p = &student;
    //之后通过指针在获取到学生内部的狗的地址赋值给狗指针
	struct Dog* dog_p = &student_p->dog;
	//通过狗指针获取狗age
	cout << dog_p->age;
}

结构体做函数参数

有两种:值传递和引用传递

struct Dog {
	string name;
	int age;
};

//定义结构体
struct Student
{
	//声明结构体中的成员
	string name;
	int score;
	int age;
	struct Dog dog;
};

//值传递
void set_value(struct Student s1) {
	s1.age = 100;
	s1.dog.age = 10;
}
//引用传递
void set_value2(struct Student* s1) {
	//设置学生年龄
	s1->age = 100;

	//设置狗的年龄
	s1->dog.age = 10;

	//这种也可以,通过指针操作
	//struct Dog* dog_p = &(s1->dog);
	//dog_p->age = 10;

}

int main()
{
	struct Dog dog = { "旺财",4 };
	struct Student student = { "小明",90,18,dog };
	
	set_value2(&student);
	cout << student.dog.age << endl;
	cout << student.age << endl;
}

结构体中使用const

struct Dog {
	string name;
	int age;
};

//定义结构体
struct Student
{
	//声明结构体中的成员
	string name;
	int score;
	int age;
	struct Dog dog;
};
struct Dog dog = { "旺财",4 };

void print(const struct Student* s) {
	struct Student student = { "老明",90,18,dog };
	s = &student;
    //s->name = "2";报错	
	cout << s->name;
}


int main()
{
	struct Student student = { "小明",90,18,dog };
	print(&student);
}

tpis: 形参接收struct 例如 void print(const struct Student* s)

你这个Student拼写错了是不会报错的,需要注意拼写,或者直接省略struct 关键字

//定义结构体
struct Student
{
	//声明结构体中的成员
	string name;
	int score;
	int age;
	struct Dog dog;
};

struct Dog dog = { "旺财",4 };

void print(struct Student* const s) {
	struct Student student = { "老明",90,18,dog };
	//s = &student; 报错
	s->name = "王哈哈";
	cout << s->name;
}


int main()
{
	struct Student student = { "小明",90,18,dog };
	print(&student);
}

结构体const和修饰普通的指针一样

const struct Student* s 形参里面的值不能改变 但是指向的地址可以改变

struct Student* const s 形参里面值可以改变,但是指向不能改变

const struct Student* const s 两个都不能变

原文地址:http://www.cnblogs.com/sunankang/p/16818151.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性