2020.12.c++基础

c++笔记

一.运算符

1.三目运算符

  • c=a>b?a:b ---------->如果a大 c=a;否则c=b
  • a>b?a:b =100 ---------->如果a大 a=100;否则b=100

2.求余以及除号的运用

一个三位数如(153),要求获取它的个位数、十位数、百位数

  • 个位:153%10=3
  • 十位:153/10=15 15%10=5
  • 百位:153/100=1

二.选择语句

1.if 和switch语句的区别

  • switch语句里面的判断只能是整型或者是字符型,不可以是一个区间。需要用到break

三.循环语句

1.while()与do....while()

  • 格式 while(){.....}------->先执行再判断
  • 格式do{.....}while();------->先判断再执行

2.break与continue

  • break;跳出循环
  • continue;跳出这次循环------>可以与if连用,进行筛选条件循环

四.数组

1.格式与初始化

  • 数据类型 数组名[数组长度];------------>自己手动赋值

  • 数据类型 数组名[数组长度]={值1,值2......};----------------->没有赋值完的,默认初始化填充为0

  • 数据类型 数组名[]={值1,值2......};------------------>长度由后面的值的多少决定

  • 注意:定义数组时,必须要有初始长度

2.一维数组名称的作用一:数组的内存空间

  • sizof(数组名);------->整个数组在内存空间的长度---->多少字节
  • sizof(数组名[0]);------->某一个元素所占的内存空间
  • sizof(数组名)/sizof(数组名[0]);--------->数组中元素的个数
  • sizeof------->用来统计一个数据类型的内存空间的大小
  • 注意:byte--1字节,short---2字节,int 类型所占的内存空间是4字节,long---8字节,float--4字节,double--8字节,char--2字节,boolean--1位

3.一维数组名称的作用二:查看数组首地址

  • cout<<数组名;----------->打印数组的首地址
  • &数组名[0];------>数组第一个元素的地址
  • 注意:数组的首地址就是数组第一个元素的地址
  • 注意:数组名是一个常量,不可以进行赋值操作

4.找数组的最大值

  • 定义一个max=0;----->与数组中的元素依次进行比较

5.数组逆置

  • 记录起始位置的下标和末位的下标
  • 两个下标互换
  • 起始下标++,末尾下标--
  • 循环条件:Start<end

6.二维数组

  • 数组名[行数] [列数];

  • 数组名[行数] [列数]={{}, {}, .....};

  • 数组名[行数] [列数]={1,2,3,4,5,6};

  • 数组名[ ] [列数]={1,2,3,4,5,6};

    注意:可以省去行数但是不能省去列数

7.二维数组名称的作用一:数组的内存空间

  • sizeof(数组名)------>二维数组占用内存空间
  • sizeof(数组名[0])------>二维数组第一行占用的内存
  • sizeof(数组名[0] [0])---->二维数组第一个元素占用内存
  • sizeof(数组名)/sizeof(数组名[0])---->二维数组的行数
  • sizeof(数组名[0])/sizeof(数组名[0] [0])----->二维数组的列数

8.一维数组名称的作用二:数组的首地址

  • cout<<数组名;----->数组的首地址
  • cout<<数组名[0];------>二维数组第一行的首地址
  • cout<<&数组名[0] [0];----->二维数组第一个元素的地址
  • 注意:三种地址都一样

五.函数

1.函数的定义

返回值类型 函数名(参数列表){

//参数列表----->需要传入的东西

....

函数体语句;

....

return 表达式;

}

注意1:如果不需要返回值,则返回值类型为void,此时可以不用写return +返回值;或者只写return;

注意2:定义函数时,这里的参数列表中的参数,是没有真实数据的,是形式参数

2.函数的调用

函数名(参数);

注意:这里的参数是实参,当调用函数时 ,实参的值会传递给形参

3.值传递

所谓的值传递就是:实参的值会传递给形参

当调用函数时,实参的值传给形参,形参改变,但是原先的实参是不变的------->形参无法改变实参

4.常见的函数样式

  • 无参无返------->常用来打印

  • 有参无返-------->用来打印这个参数

  • 无参有返---------->调用函数时得到的就是这个返回值

    int test(){

    ....

    return 1000;

    }

  • 有参有返,可以返回这个参数,return 参数;

5.函数的声明

  • 函数的声明可以多次,但是函数的定义只能有一次
  • 函数的声明的格式:返回值类型 函数名(参数列表);
  • 函数声明的作用,告诉运行程序自己要调用这个函数,如果main函数写在前,防止无法识别。

6.函数的分文件编写

函数分文件编写的主要步骤

  • 1)创建.h后缀名的头文件

​ 需要加#include <iostream.h>

​ using namespace std;

​ 这是框架。

  • 2)创建.cpp后缀的源文件

    需要加#include “头文件名”

  • 3)在头文件中写函数的声明

  • 4)在源文件中写函数的定义

  • 5)在运用时,就include这个函数的头文件就好了

7.有特点的的函数:获取随机数

rand()函数得到0~32767之间的随机数

rand()%100得到0~99之间的随机数

rand()%100+1得到1~100之间的随机数

注意:可以添加随机数种子,利用当前系统的时间生成随机数,防止每次生成的随机数是一样的

# include <ctime>//时间系统头文件
srand((unsigned int)time(NULL));

六.指针

1.定义指针

  • 指针定义的语法:

​ 数据类型 *指针变量名

eg: int *p;

​ int a=10;

​ p=&a;

指针p就是a的地址

2.使用指针

可以通过解引用的方式找到指针所指向的内存

指针前面加*代表解引用,找到指针指向内存的数据

eg: *p=1000; //修改了指针所指的内容

3.指针所占的内存空间

  • 在32位操作系统下,占用4字节

  • 在64位操作系统下,占用8字节

    eg: int * p=&a;

    *int 是指针的数据类型

    cout<<sizeof(int *);与cout<<sizeof(p);等价

  • **不管是什么数据类型的指针都遵循上述规律,float 、int 、double * 都是一样的数据空间

    4.空指针

  • int *p;-------->指针变量p指向的内存空间的编号为0的空间 也可写做 int *p =NULL;

  • 空指针是不能进行访问的

    要是后续代码中 未给指针初始化 而出现了 *p=100;或者打印 *p 的操作,都是不行的,因为内存编号从0~255为系统占用的内存,不允许用户访问

5.野指针

  • 避免使用 如 int *p=(int *)0x1100;

    将数字转换成指针类型(地址)然后赋给指针,当你利用解引用*p时,是没有权限访问该内容的。

6.const 修饰指针的三张情况

  • 1)const 修饰指针------->常量指针

const int * p=&a;

或者

int const * p=&a;

特点:指针的指向可以修改,但是指针的值不可以修改

原因:const修饰的是*p,是一个值

  • 2)const 修饰常量------->指针常量

int* const p=&a;//指针常量

特点:指针的指向不可以修改,但是指针的值可以修改

原因:const修饰的是p,是一个指针

  • 3)const 即修饰指针,也修饰常量

const int * const p=&a;

特点:指针的指向不可以修改,但是指针的值也不可以修改


怎么读:看定义式,const为常量,*为指针

7.指针和数组

数组名就是指针的首地址

int arr[10]={1,2,3,4,5,6,7,8,9,10};

int *p=arr;//arr就是数组的首地址
cout<<*P<<endl;//打印首地址的元素
p++;//指针偏移四个字节,因为int*是4字节的内存空间
cout<<*P<<endl;//打印下一地址的元素

8.指针和函数(值传递和地址传递)

  • 1)值传递(见上面五.3的内容)-------->形参不可以修饰实参
  • 2)地址传递----->形参可以修饰实参
#include <iostream>;
using namespace std;
void swap(int m,int n) {
	int temp = m;
	m = n;
	n = temp;
	cout << "swap:a =" << m << endl;
	cout << "swap:b =" << n << endl;
}

void swap2 (int* m, int* n) {
	int temp = *m;
	*m = *n;
	*n = temp;
	cout << "swap2:a =" << *m << endl;
	cout << "swap2:b =" << *n << endl;
}
int main() {
	int a = 10;
	int b = 20;
    //swap(a,b)
	swap2(&a, &b);
	cout<<"a ="<< a<<endl;
	cout<<"b ="<< b<<endl;
}
/*
结果(使用swap(a,b)):
swap:a =20
swap:b =10
a =10
b =20
结果(使用swap2(&a,&b)):
swap2:a =20
swap2:b =10
a =20
b =10
*/

总结:如果不想修改实参,就用值传递;如果想修改实参,就用地址传递;

9.指针和数组和函数

#include <iostream>;
using namespace std;
void bubbleSort(int *arr,int length) {
	for (int i = 0; i < length-1; i++) {
		for (int j = 0; j < length - 1 - i; j++) {
			if (arr[j] < arr[j + 1]) {
				int temp = arr[j+1];
				arr[j + 1] = arr[j];
				arr[j] = temp;
			}
		}
	}
}
void printArray(int *arr,int length) {
	for (int i = 0; i < length; i++) {
		cout << arr[i]<<endl;
	}
}

int main() {
	int arr[10] = { 5,6,3,4,2,10,9,1,8,7};
	int len = sizeof(arr) / sizeof(arr[0]);
	bubbleSort(arr,len);
	printArray(arr, len);

}
/*
结果:
10
9
8
7
6
5
4
3
2
1
*/

七.结构体

1.结构体的基本概念

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

2.结构体的定义和使用

1)结构体定义语法:struct 结构体名{结构体成员列表};

2)创建结构体的一个变量

  • struct 结构体名 变量名
  • struct 结构体名 变量名=
  • 定义结构体时顺便创建变量
//struct结构体的使用
#include <iostream>;
#include <String>;
using namespace std;

struct Student {
	string name;
	int age;
	float score;
}s3;
int main() {
	//通过学生类创建一个具体的学生
	//方法一
	struct Student s1;
	s1.name = "aaa";
	s1.age = 10;
	s1.score = 99;
	//方法二
	struct Student s2{"bbb",11,89 };
	//方法三:直接在构造体后创建
	s3.name = "ccc";
	s3.age = 9;
	s3.score = 95;
	cout << s1.age << s1.name << s1.score << endl;
	cout << s2.age << s2.name << s2.score << endl;
	cout << s3.age << s3.name << s3.score << endl;
}
/*结果:
10aaa99
11bbb89
9ccc95
*/

定义结构体时的关键字是struct,不可省略

创建结构体时的关键字是struct,可以省略

3.结构体数组

1)作用:将自定义的结构体放入到数组中方便维护

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

//结构体数组
#include <String>;
#include <iostream>
using namespace std;

struct Student {
	string name;
	int age;
	float score;
};

int main() {
	//创建结构体数组,并赋值
	struct Student studentArray[3]
	{
		{ "aaa",10,99},
		{ "bbb",11,89},
		{ "ccc",9,95}
	};
	//给结构体数组中的元素赋值
	studentArray[2].age = 20;
	studentArray[2].name ="ddd" ;
	studentArray[2].score =100;
	//遍历元素
	for (int i = 0; i <= 2; i++) {
		   cout << studentArray[i].age
			<< studentArray[i].name
			<< studentArray[i].score<<endl;
	}

}
/*
结果:
10aaa99
11bbb89
20ddd100
*/

4.结构体指针

//结构体指针
#include <String>;
#include <iostream>
using namespace std;

struct Student {
	string name;
	int age;
	float score;
};
int main() {
	//1.创建结构体变量(struct可以省略)
	struct Student s1 = { "aaa",10,99 };
	//2.通过指针指向结构体变量(struct可以省略)
	struct Student* p = &s1;
	//3.通过指针访问结构体变量的数据
	//通过结构体指针 访问的结构体的属性,需要利用“->”符号
	cout << p->age  << p->name << p->score << endl;
}
/*
结果:10aaa99
*/

5.结构体嵌套另外一个结构体

在结构体中可以定义另外一个结构体作为成员,(被嵌套的也就是另一个)结构体需要定义在前

//结构体嵌套结构体
#include <String>;
#include <iostream>
using namespace std;

struct Student {
	string name;
	int age;
	float score;
};

//新定义一个结构体用来嵌套上面的结构体成员
struct Teacher {
	string name;
	int age;
   struct Student s1;//子结构体中的学生s1
   //此处的struct 可以省略(创建一个子结构体的成员)
};

int main() {
	struct Teacher t1;
	t1.age = 30;
	t1.name = "hhh";
	t1.s1.age = 10;
	t1.s1.name ="aaa" ;
	t1.s1.score=99;
	cout << "老师姓名: " << t1.name << endl;
	cout<<"老师年龄: " << t1.age << endl;
	cout << "辅导学生姓名: " << t1.s1.name << endl;
	cout << "辅导学生年龄: " << t1.s1.age << endl;
    cout<<"辅导学生成绩: "<<t1.s1.score<< endl;
}
/*结果:
老师姓名: hhh
老师年龄: 30
辅导学生姓名: aaa
辅导学生年龄: 10
辅导学生成绩: 99
*/

6.结构体作为函数参数(值/地址传递)

结论同上:如果不想修改实参,就用值传递;如果想修改实参,就用地址传递;

//结构体作为函数参数(值传递/地址传递)
#include <String>;
#include <iostream>
using namespace std;

struct Student {
	string name;
	int age;
	float score;
};

void printStudent1(struct Student s) {
	s.age = 100;
	cout <<"printStudent1值传递下形式参数:"<< s.age << s.name << s.score << endl;
}

void printStudent2(struct Student* p) {
	p->age = 200;
	cout << "printStudent2地址传递下形式参数:" << p->age << p->name << p->score << endl;
}
//!!!要求:结构体作为函数参数,将创建出来的成员作为函数的参数
//实现打印这个成员的属性的函数
int main() {
	struct Student s1 = { "aaa",10,99 };
	printStudent1(s1);
	//printStudent2(&s1);
	cout << "main函数下实际参数:" << s1.age << s1.name << s1.score << endl;
}
/*结果:使用printStudent1(struct Student s) 值传递
printStudent1值传递下形式参数:100aaa99
main函数下实际参数:10aaa99
结果:使用printStudent2(struct Student s)地址传递
printStudent2地址传递下形式参数:200aaa99
main函数下实际参数:200aaa99
*/

注意1:当结构体作为函数参数时,常使用的形式参数是指针。原因是指针的内存空间是4字节,可以节省内存空间,而且不会复制出全部的信息出来

注意2:但是使用指针作为形式参数,是地址传递,为了防止 误操作(修改形参的值)常运用const----> const Student * s

7.结构体例题排序

//设计一个英雄结构体,包括姓名,年龄和性别。
//创建结构体数组,数组中存放5名英雄
//通过冒泡排序算法,按照年龄进行排序,最终打印结果
#include <String>;
#include <iostream>
using namespace std;

struct Hero {
    string name;
    int age;
    string sex;
};

void Bubblesort(struct Hero heroArray[],int length){
    for (int i = 0; i < length - 1; i++) {
        for(int j=0;j<length-j-1;j++)
            if (heroArray[j].age> heroArray[j + 1].age) {
                Hero temp = heroArray[j];
                heroArray[j ] = heroArray[j+1];
                heroArray[j+1] = temp;
            }
    }
}

void Printfarray(Hero heroArray[], int length) {
    for (int i = 0; i < length; i++)
    {
        cout << "姓名:" << heroArray[i].name << "  年龄: " << heroArray[i].age 
             << "  性别: " << heroArray[i].sex << endl;
    }
}

int main() {
    //创建结构体数组
    struct Hero heroArray[5]{
        {"aaa",15,"男"},
        {"bbb",10,"女"},
        {"ccc",5,"男"},
        {"ddd",20,"男"},
        {"eee",25,"女"},
    };
    int len = sizeof(heroArray) / sizeof(heroArray[0]);
    Bubblesort(heroArray, len);//这里的heroArray是数组的首地址
    Printfarray(heroArray, len);
}
posted @ 2020-12-09 20:25  维他命D片  阅读(75)  评论(0编辑  收藏  举报