目录
数组 函数 指针 结构体 基本知识
# include <iostream>
# include <string> // 使用C++风格字符串时候,要包含这个头文件
# include <math.h>
using namespace std;
// 数据类型 数组名[数组长度]
// int arr[5];
// arr[0]=0;
// 数据类型 数组名[数组长度]={值1,值2...}
// int arr2[5]={1,2,3,4,5}; //如果没有填写数字,对应为位置0填写
// 数据类型 数组名[]={值1,值2}
// int arr3[]={1,2,3,4,5}; //定义数组的时候,必须有初始长度
// 放在一块连续的内存中
// 数组中每个元素都是相同数据类型
// 数组名用途
// 可以通过数组名统计整个数组占用内存大小
/* cout<<"整个数组占用内存空间为"<<sizeof(arr1)<<endl;
cout<<"数组中每个元素占用内存空间为"<<sizaof(arr1[0])<<endl;
cout<<"数组总共有元素个数"<<sizeof(arr1)/sizeof(arr1/arr1[0])<<endl;
*/
// 可以通过数组名查看数组首地址
/*
cout<<"数组首地址为"<<arr1<<endl;
cout<<"数组首地址为"<<&arr1[0]<<endl;
*/
// 数组名是常量不可以进行赋值
// 二维数组定义方式
/*
数据类型 数组名[行数][列数];
数据类型 数组名[行数][列数] = {{数据1,数据2},{数据3,数据4}};
数据类型 数组名[][列数]={数据1,数据2,数据3,数据4};
*/
// 二维数组组数组名
// 可以查看占用内存空间大小
// 可以查看二维数组的首地址
// 函数的定义 将一段经常使用的代码封装起来,减少重复代码
// 一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能
/*
返回值类型 函数名(参数列表)
{
函数体语句
return 表达式
}
*/
// 函数的分文件编写
// 创建.h后缀名的头文件
// 创建.cpp后缀名的源文件
// 在头文件中写函数的声明
// 在源文件中写函数的定义
// 指针 可以通过指针间接访问内存
// 内存编号是从0开始记录的,一般用十六进制数字表示
// 可以利用指针变量保存地址
// 指针所占用的内存空间 指针也是种数据类型,同样占用内存空间
// 32位操作系统占用4位,64位操作系统占用8位(无论是char int float string)
// 空指针和野指针
// 空指针 指针变量指向内存中编号为0的空间
// 初始化指针变量 空指针指向的内存是不可以访问的
// int * p = NULL;
// *p = 100; cout<<*p<<endl; 系统会运行错误,内存0~255为系统占用内存,不允许用户访问
// 野指针 指针变量指向非法的内存空间
// int *p = (int *)0x1100;cout<<*p<<endl;
// 访问野指针错误,不是我们申请的空间,没有权利访问。
// 在程序中要避免野指针
// const 修饰指针
// const 修饰指针 ---常量指针
// int a=10,b=10;
// const int *p = &a;
// 指针指向的值不能改,指针的指向可以修改。
// 错误:*p = 20;正确:p = &b;
// const 修饰常量 ---指针常量
// 指针指向的值可以修改,指针指向不能修改
//int * const p2 = &a;
// 错误:p2 = &b;正确:* p2 =b
// const 即修饰指针,又修饰常量
// 指向和值都不能修改
// const int * const p3 = &a;
// 错误:p2 = &b;错误 * p2 =b
// 指针和数组 利用指针访问数组元素
// int arr[10] = {1,2,3,4,5,6,7,8,9,10};
// int *p = arr;//arr就是数组首地址
// *p = 1; p++就指向了2
// 指针和函数
// 1、值传递
// 在函数中值传递时,形参会改变、实参不会改变
// 2、地址传递
// 可以改变实参的数值,因为操作的直接是实参
// 结构体 结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
// 语法:struct 结构体名{ 结构体成员 };
// struct 结构体名 变量名
// struct student s1;
// s1.name = "张三";
// s1.age = 18;
// s1.score = 100;
// cout<<"姓名: "<<s1.name<<" 年龄: "<<s1.age<<" 分数: "<<s1.score<<endl;
// struct 结构体名 变量名={成员1值,成员2值}
// struct student s2 = {"李四",19,90};
// cout<<"姓名: "<<s2.name<<" 年龄: "<<s2.age<<" 分数: "<<s2.score<<endl;
// 定义结构体时顺便创建变量
结构体
// struct student{
// // 姓名
// string name;
// // 年龄
// int age;
// // 分数
// int score;
// }s3; //定义结构体时顺便创建变量
// 定义结构体时关键字是struct,不可省略
// 创建结构体变量时,关键字struct可以省略
// 结构体变量利用操作符"."访问成员
// 结构体数组 将定义的结构体放入到数组中方便维护
// 1,定义结构体
//struct student{
// string name;
// int age;
// int score;
//};
// 2,创建结构体数组
//struct student stuarry[3] = {
// {"张三",18,100 },
// {"李四",28,89 },
// {"王五",38,66}
//};
// 3,给结构体数组的元素赋值
//stuarry[2].name = "赵六";
//stuarry[2].age = 80;
//stuarry[2].score = 70;
// 4, 遍历结构体数组
//for(int i =0;i<3;i++){
// cout<<"姓名:"<<stuarry[i].name
// <<" 年龄:"<<stuarry[i].age
// <<" 分数:"<<stuarry[i].score<<endl;
//}
// 语法 struct 结构体名 数组名[元素个数]={{},{},...{}}
// 结构体指针 通过指针访问结构体中的成员
// 利用操作符->可以通过结构体指针访问结构体属性
// 结构体嵌套结构体 结构体中的成员可以是另外一个结构体
// 例如每个老师辅导一个学员,一个老师的结构体中,记录一个学习的结构体
// 结构体做函数参数 将结构体作为参数向函数中传递
// 传递方式有两种 值传递和地址传递
// 打印函数,值传递 //值传递不改变实参,地址传递改变实参
//void print1(struct student s){
// cout<<"姓名:"<<s.name<<"年龄:"<<s.age<<"分数"<<s.score<<endl;
//}
// 地址传递 可以减少内存空间,而且不会复制新的副本
//void print2(struct student *s){
// cout<<"姓名:"<<s->name<<" 年龄:"<<s->age<<" 分数:"<<s->score<<endl;
//}
// 结构体中const使用场景 用const来防止误操作
// struct student *s 改成 struct const student *s
// 结构体只能读取,不能修改故防止了误操作
//
// 冒泡排序函数
void bubbleSort(int *arr,int len){
for(int i=0; i<len; i++){
for(int j=i+1; j<len;j++){
int temp;
if (*(arr+i)< *(arr+j))
{
temp = *(arr+i);
*(arr+i) = *(arr+j);
*(arr+j) = temp;
}
//if (arr[i]< arr[j])
// {
// temp = arr[i];
// arr[i] = arr[j];
// arr[j] = temp;
// }
}
}
}
// 交换两数函数
void swap(int *a,int *b){
int temp = *a;
*a = *b;
*b = temp;
}
// 加法函数
int add(int num1,int num2)
{
int sum;
sum = num1 + num2;
return sum;
}
struct student{
// 姓名
string name;
// 年龄
int age;
// 分数
int score;
}s3; //定义结构体时顺便创建变量
struct teacher{
string id;
string name;
int age;
student stu;
};
// 打印函数,值传递 //值传递不改变实参,地址传递改变实参
void print1(struct student s){
cout<<"姓名:"<<s.name<<"年龄:"<<s.age<<"分数"<<s.score<<endl;
}
// 地址传递
void print2(struct student *s){
cout<<"姓名:"<<s->name<<" 年龄:"<<s->age<<" 分数:"<<s->score<<endl;
}
int main(){
int arr1[5];
int arr2[5]={1,2,3,4,5};
int arr3[]={1,2,3,4,5};
cout<<"整个数组占用内存空间为"<<sizeof(arr1)<<endl;
cout<<"数组中每个元素占用内存空间为"<<sizeof(arr1[0])<<endl;
cout<<"数组总共有元素个数"<<sizeof(arr1)/sizeof(arr1[0])<<endl;
cout<<"数组首地址为"<<arr1<<endl;
cout<<"数组首地址为"<<&arr1[0]<<endl;
// 五只小猪称体重
int arr[5]={300,350,200,400,250};
int b=arr[0],j=0;
for(int i=0;i<5;i++){
b<arr[i]?b=arr[i]:j++;
}
cout<<"最重的小猪是"<<b<<endl;
// 数组元素逆置
cout<<"数组逆置前"<<endl;
for(int i=0;i<sizeof(arr2)/sizeof(arr2[0]);i++){
cout<<arr2[i]<<"\t"<<endl;;
}
for(int i=0;i<sizeof(arr2)/sizeof(arr2[0]);i++){
int temp =0;
if(4-i!=i){
temp=arr2[4-i];
arr2[4-i]=arr2[i];
arr2[i]=temp;
}
else{
break;
}
}
cout<<"数组逆置后"<<endl;
for(int i=0;i<sizeof(arr2)/sizeof(arr2[0]);i++){
cout<<arr2[i]<<"\t"<<endl;;
}
// 冒泡排序 对数组进行升序或者降序排列
int arr4[6],flag;
cout<<"请输入要排序的6个数"<<endl;
for(int i =0;i<sizeof(arr4)/sizeof(arr4[0]);i++){
cin>>arr4[i];
}
F :cout<<"请输入1升序排列,2降序排列"<<endl;
cin>> flag;
for(int i =0;i<sizeof(arr4)/sizeof(arr4[0]);i++){
int temp =0;
for(int j=i+1;j<sizeof(arr4)/sizeof(arr4[0]);j++){
switch(flag){
case 1:
if(arr4[i]<arr4[j]){
temp=arr4[i];
arr4[i]=arr4[j];
arr4[j]=temp;
}continue;
case 2:
if(arr4[i]>arr4[j]){
temp=arr4[i];
arr4[i]=arr4[j];
arr4[j]=temp;
}continue;
default:cout<<"你的输入有误,请重新输入"<<endl;
goto F;
}
}}
if(flag==1){
cout<<"你选择的是升序排列"<<endl;
}
else{
cout<<"你选择的是降序排列"<<endl;
}
for(int i =0;i<sizeof(arr4)/sizeof(arr4[0]);i++){
cout<<arr4[i]<<endl;
}
//二维数组
int arr5[2][3] ={
{1,2,3},{1,2,3}
};
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
cout<<arr5[i][j]<<" ";
}
cout<<endl;
}
int arr6[][3] ={1,2,3,4,5,6};
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
cout<<arr6[i][j]<<" ";
}
cout<<endl;
}
cout<<"二维数组占用内存空间为:"<<sizeof(arr5)<<endl;
cout<<"二维数组第一行占用内存为"<<sizeof(arr5[0])<<endl;
cout<<"二维数组第一个元素占用内存空间为"<<sizeof(arr5[0][0])<<endl;
cout<<"二维数组首地址为"<<arr5<<endl;
// 考试成绩输出
int arr7[3][3]={{100,100,100},
{90,50,100},
{60,70,80}};
string arr8[3] = {"张三","李四","王五"};
// char arr8[3][7]={"张三","李四","王五"};//一个汉字三个字节,两个占六个字节。
//末尾接一个\0,故两个汉字占7个字节
// string 定义的是字符串,char定义的是一个字符
for(int i=0;i<3;i++){
int b=0;
for(int j=0;j<2;j++){
b+=arr7[i][j];
}
cout<<arr8[i]<<"的总成绩为 "<<b<<endl;
}
cout<<add(1,2)<<endl;
// 定义指针 数据类型 *指针变量名
int o = 10;
int * p;
p = &o;
cout<<"o的地址为"<<& o<<endl;
cout<<"p的值为"<<p<<endl;
// 使用指针,可以通过解引用的方式找到指针指向的内存
// 指针前加*代表解应用,找到指针指向的内存中的数据
*p = 1000;
cout<<"o="<<o<<endl;
cout<<"*p ="<<*p<<endl;
cout<<"指针占用内存空间为"<<sizeof(int *)<<endl;
//const 修饰指针
int o1=10,o2=20;
cout<<o1<<endl;
int * const p1 = &o1;
*p1=o2;
cout<<o1<<endl;
// 指针遍历数组
int arr9[]={1,2,3,4,5,6,7};
int *p2 = arr9;
for(int i=0;i<7;i++){
cout<<*p2<<endl;
p2++;
}
// 指针与函数 地址传递 改变了实参的数
int num1 =10,num2 = 20;
cout<<"交换之前的数"<<endl<<num1<<" "<<num2<<endl;;
swap(&num1,&num2);
cout<<"交换之后的数"<<endl<<num1<<" "<<num2<<endl;;
// 冒泡排序
int arr10[7] ={1,3,4,5,6,18,45};
int len = sizeof(arr10)/sizeof(arr10[0]);
cout<<len<<endl;
int *p3 = arr10;
for(int i =0;i<sizeof(arr10)/sizeof(arr10[0]);i++) {
cout<<"数组排序前为"<<*p3<<endl;
*p3++;
}
bubbleSort(arr10,len);
for(int i =0;i<sizeof(arr10)/sizeof(arr10[0]);i++) {
cout<<"数组降序排序为"<<arr10[i]<<endl;
}
// 结构体定义
struct student s1;
s1.name = "张三";
s1.age = 18;
s1.score = 100;
cout<<"姓名: "<<s1.name<<" 年龄: "<<s1.age<<" 分数: "<<s1.score<<endl;
struct student s2 = {"李四",19,90};
cout<<"姓名: "<<s2.name<<" 年龄: "<<s2.age<<" 分数: "<<s2.score<<endl;
s3.name = "王五";
s3.age = 20;
s3.score = 89;
cout<<"姓名: "<<s3.name<<" 年龄: "<<s3.age<<" 分数: "<<s3.score<<endl;
// 结构体数组
struct student stuarry[3] = {
{"张三",18,100 },
{"李四",28,89 },
{"王五",38,66}
};
// 3,给结构体数组的元素赋值
stuarry[2].name = "赵六";
stuarry[2].age = 80;
stuarry[2].score = 70;
//4, 遍历结构体数组
for(int i =0;i<3;i++){
cout<<"姓名:"<<stuarry[i].name
<<" 年龄:"<<stuarry[i].age
<<" 分数:"<<stuarry[i].score<<endl;
}
// 结构体指针
student *p4 = &s1;
//
cout<<"姓名:"<<p4->name<<" 年龄:"<<p4->age<<"分数:"<<p4->score<<endl;
// 结构体嵌套
teacher t = {"001","老万",60,"小万",20,60};
cout<<"老师:"<<t.name<<" 老师id:"<<t.id<<" 老师年龄:"<<t.age
<<" 学生姓名:"<<t.stu.name<<" 学生年龄:"<<t.stu.age<<" 学生分数:"<<t.stu.score<<endl;
// 结构体做函数参数
cout<<"值传递"<<endl;
print1(s1);
cout<<"地址传递"<<endl;
print2(&s1);
system("pause");
return 0;
}
案例
1、结构体案例1 输出老师学生表格
# include <iostream>
# include <string>
using namespace std;
# include <stdlib.h>
# include <ctime>
struct student{
string name;
int score;
};
struct teacher{
string name;
student s[5];
};
void fuzhi(teacher *p,string tname,string sname[5],int s[5]){
p->name = tname;
cout<<"老师:"<<p->name
<<endl;
for(int i=0;i<5;i++){
p->s[i].name = sname[i];
p->s[i].score = s[i];
cout<<"\t学生:"<<p->s[i].name<<" 成绩:"<<p->s[i].score<<endl;
}
}
int main(){
string tname[3]={"李老师","王老师","陈老师"};
string t[3][5]={{"小明","小王","小赵","小陈","小名"},
{"小就","小都","小发","小放","小五"},
{"小对","小地","小大","小分","小复"}};
int s[3][5];
srand((unsigned int)time(NULL)); //随机数种子
for(int i=0;i<3;i++){
for(int j=0;j<5;j++){
s[i][j] = rand()%61+40; // 成绩取值40-100
}
}
//int s[3][5]={{23,32,43,42,42},
// {56,32,43,42,42},
// {23,67,43,62,42}};
teacher th[3];
for(int i=0;i<3;i++){
fuzhi(&th[i],tname[i],t[i],s[i]);
}
// 通过指针赋值,改变了结构体的值
//cout<<"老师:"<<th1.name
// <<endl<<"学生:"<<th1.s1.name<<" 成绩:"<<th1.s1.score
// <<endl<<"学生:"<<th1.s2.name<<" 成绩:"<<th1.s2.score
// <<endl<<"学生:"<<th1.s3.name<<" 成绩:"<<th1.s3.score
// <<endl<<"学生:"<<th1.s4.name<<" 成绩:"<<th1.s4.score
// <<endl<<"学生:"<<th1.s5.name<<" 成绩:"<<th1.s5.score<<endl;
}
2、结构体案例2 依据年龄,对结构体的数据进行排序
#include <iostream>
#include <string>
using namespace std;
struct hero{
string name;
string sex;
int age;
};
void paixu(struct hero p[],int len){
for(int i=0;i<len;i++)
for(int j=i+1;j<len;j++){
if(p[i].age>p[j].age){
hero s3 = p[j];
p[j] = p[i];
p[i] = s3;
}
}
}
void print(struct hero p[],int len){
for(int i = 0;i<len;i++){
cout<<" 姓名:"<<p[i].name
<<" 性别:"<<p[i].sex
<<" 年龄:"<<p[i].age<<endl;
}
}
int main(){
hero sanguo[5]={{"刘备","男",23},
{"关羽","男",22},
{"赵云","男",21},
{"张飞","男",21},
{"貂蝉","男",19}
};
int len = sizeof(sanguo)/sizeof(sanguo[0]);
paixu(sanguo,len);
print(sanguo,len);
}
3、通讯录系统项目
实现按数字实现对应功能1、添加联系人
2、显示联系人
3、删除联系人
4、查找联系人
5、修改联系人
6、清空联系人
0、退出通讯录
小项目分文件创造在devc++里面创建,在刚开始并没有找到相关资料,以为不能分文件,不过该ide能创建项目,项目是个空项目,后面发现,需要自己手动添加头文件和源文件,在添加.h和.cpp文件。
main函数:
#include<iostream>
#include<string>
#include"act.h"
using namespace std;
//struct person{
// //姓名、性别、年龄、联系电话、家庭住址
// string name;
// string sex;
// int age;
// int num;
// string home;
//};
//struct adl{
// int size; //通讯录当前人数
// struct person perary[MAX];
//};
void showmenu(){
cout<<"*********************"<<endl
<<"****1、添加联系人****"<<endl
<<"****2、显示联系人****"<<endl
<<"****3、删除联系人****"<<endl
<<"****4、查找联系人****"<<endl
<<"****5、修改联系人****"<<endl
<<"****6、清空联系人****"<<endl
<<"****0、退出通讯录****"<<endl
<<"*********************"<<endl;
}
int main(){
adl abs;
abs.size = 0;
int flg;
while(true){
showmenu();
cin>>flg;
switch(flg){
case 1:
add(&abs);
break;
case 2:
show(abs,abs.size);break;
case 3:
del(&abs);
break;
case 4:
search(&abs);break;
case 5:
change(&abs);break;
case 6:
clear(&abs);break;
case 0:
cout<<"欢迎下次使用"<<endl;
system("pause");
return 0;
break;
default:
cout<<"你的输入有误,请重新输入"<<endl;
system("pause");
system("cls");
}
}
}
act.cpp文件:
#include"act.h"
//添加联系人
void add(struct adl *p){
if(p->size==MAX){
cout<<"通讯录人数已满"<<endl;
}
else{
cout<<"请输入姓名"<<endl;
cin>>p->perary[p->size].name;
cout<<"请输入性别"<<endl;
cin>>p->perary[p->size].sex;
cout<<"请输入年龄"<<endl;
cin>>p->perary[p->size].age;
cout<<"请输入号码"<<endl;
cin>>p->perary[p->size].num;
cout<<"请输入住址"<<endl;
cin>>p->perary[p->size].home;
p->size++;
cout<<"添加成功"<<endl;
cout<<"当前人数"<<p->size<<"还剩名额"<<MAX-p->size<<endl;
}
system("pause");// 按任意键继续
system("cls");//清空屏幕
}
// 显示联系人
void show(struct adl p,int len){
if(p.size!=0){
for(int i=0;i<len;i++){
cout<<"姓名:"<<p.perary[i].name
<<"\t性别:"<<p.perary[i].sex
<<"\t年龄:"<<p.perary[i].age
<<"\t号码:"<<p.perary[i].num
<<"\t住址:"<<p.perary[i].home<<endl;
}
cout<<"目前通讯录:"<<p.size<<"人"<<endl
<<"空间还剩:"<<1000-p.size<<"人"<<endl;}
else{
cout<<"目前通讯录为空"<<endl;
}
system("pause");// 按任意键继续
system("cls");//清空屏幕
}
// 检测联系人是否存在
int isexist(adl *p,string name){
for(int i = 0;i<p->size;i++){
if (p->perary[i].name==name)
{
return i;
}
}
return -1;//没有检测到返回-1
}
// 删除联系人
void del (struct adl *p)
{
string name;
cout<<"请输入删除联系人姓名:"<<endl;
cin>>name;
int tem = isexist(p,name);
if(tem!=-1){
for(int i = tem+1;i<p->size;i++){
p->perary[i-1]=p->perary[i];
}
p->size--;
cout<<"删除成功"<<endl;
}
else{
cout<<"查无此人"<<endl;
}
system("pause");// 按任意键继续
system("cls");//清空屏幕
}
void search(adl *p){
cout<<"请输入查找联系人姓名:"<<endl;
string name;
cin>>name;
int tem = isexist(p,name);
if (tem == -1){
cout<<"你查找的联系人不存在"<<endl;
}
else{
cout<<"查找成功:"<<endl<<"姓名:"<<p->perary[tem].name
<<"\t性别:"<<p->perary[tem].sex
<<"\t年龄:"<<p->perary[tem].age
<<"\t号码:"<<p->perary[tem].num
<<"\t住址:"<<p->perary[tem].home<<endl;
}
system("pause");// 按任意键继续
system("cls");//清空屏幕
}
void change(adl *p){
cout<<"请输入修改联系人姓名:"<<endl;
string name;
cin>>name;
int tem = isexist(p,name);
if (tem == -1){
cout<<"你要修改的联系人不存在"<<endl;
}
else{
cout<<"查找成功:"<<endl<<"姓名:"<<p->perary[tem].name
<<"\t性别:"<<p->perary[tem].sex
<<"\t年龄:"<<p->perary[tem].age
<<"\t号码:"<<p->perary[tem].num
<<"\t住址:"<<p->perary[tem].home<<endl;
cout<<"请输入修改的名字"<<endl;
cin>>p->perary[tem].name;
cout<<"请输入修改的性别"<<endl;
cin>>p->perary[tem].sex;
cout<<"请输入修改的年龄"<<endl;
cin>>p->perary[tem].age;
cout<<"请输入修改的电话"<<endl;
cin>>p->perary[tem].num;
cout<<"请输入修改的家庭住址"<<endl;
cin>>p->perary[tem].home;
}
system("pause");// 按任意键继续
system("cls");//清空屏幕
}
void clear(adl *p){
cout<<"请确定是否要清空通讯录"<<endl<<
"\t1 确定,2返回"<<endl;;
int tem;
cin>>tem;
if(tem == 1){
p->size = 0;
}
else{
system("pause");// 按任意键继续
system("cls");//清空屏幕
}
}
act.h文件:
#include<iostream>
#include<string>
#define MAX 1000
using namespace std;
struct person{
//姓名、性别、年龄、联系电话、家庭住址
string name;
string sex;
int age;
int num;
string home;
};
struct adl{
int size; //通讯录当前人数
struct person perary[MAX];
};
// 增加联系人
void add(struct adl *p);
// 显示联系人
void show(struct adl p,int len);
// 检测目标联系人是否存在
int isexist(adl *p,string name);
// 删除联系人
void del (struct adl *p);
// 查找联系人
void search(struct adl *p);
// 修改联系人
void change(adl *p);
// 清空联系人
void clear(adl *p);