文章目录
章节12 13 字符串-字符数组
课题62_值的引用传递
int a = 10;
按值传递:就是按副本传递,实参直接是a
引用传递:指在调用函数时,将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。也就是说,我们在进行实参传递时,传递&a(a的地址),函数体使用的时候*num。
课题63_数组函数参数
数组座位参数传递时,实际采用传址方式。
c里面不能返回数组
题目:书写一个小型的学生成绩管理系统
思路:三个函数1.录入 2.排序 3.按照某格式打印
课题64 65_使用头文件
头文件:创建.h文件,一般放一些重复使用的代码,例如函数声明,变量声明,常量定义,宏的定义等。
实现文件:创建.c文件,源文件。(包含自定义头文件时没使用双引号#include"our.h")
题目:设计一个程序让用户指定酒店和入住的天数,然后计算并显示总费用。
课题66_初识字符串与字符数组
字符串:”My love“;双引号不是字符串的一部分,仅用来告知编译器括起来的是字符串;c语言每个存储单元占一个字节,最后一个字符是\0(空字符),空字符是字符串的终止符,不是NULL。
判断题:
所有的字符串都是字符数组 正确
所有的字符数组都是字符串 错误
char name1[] = {'a', 'b', '\0'};
char name2[] = {"ab"};
课题67_get puts函数补充
char name1[] = {'a', 'b', '\0'};
char name2[] = {"ab"};
gets(name2)//scanf("%s", name)
gets函数不对接受字符串的buffer进行边界检测,会造成越界,从而产生bug
char name1[] = {'a', 'b', '\0'};
char name2[] = {"ab"};
fgets(name2,10,stdir);
fgets fgets(words1,20,stdio ) 可以规定读入字符的长度,默认最后一个添加一个回车
puts(words)
课题68_字符串小结
三种方式录入字符串:
scanf("%s",str);
get(str);
fgets(str,50,stdin);
课题69 70 71_常用字符串操作函数
strlen函数:计算字符串的实际长度,不计算’\0’
字符串的复制:a = b;此处是把常量地址赋过去,因为字符串隐含了一个特性:常量,数组的赋值原理,每个元素逐个进行复制
strcpy(str2,str1)
字符串的比较:将两个字符串从首字母开始,按照ASCII码的顺序进行逐个比较
strcmp(str2,str1)
字符串的连接:将一个字符串连接到另一个字符串的末尾,组合成一个新的字符串
strcat(str1,str2) ,要保证第一个字符串str1够用,把str2到‘\0’都复制进去
字符串加密
加密方式:将字符串中的每个字符加上它在字符串中的位置和一个偏移量5
业界常用:MD5
课题72_指向字符串的指针
指针指向字符串
1.可以指向常量字符串
2.可以指向存储字符串的字符数组
char * words = "My heart is still";
words +=9;
puts(words)
数组形式和执行形式的不同
1.初始化字符数组时会把静态存储区的字符串拷贝到数组中
2.初始化指针时,只把字符串的地址拷贝给指针
//字符数组**拷贝**
char chi1[8] = {'a','b','c'};
//字符串
char chi1[] = {'a','b','c','\0'};
char ch3[] = "abc";
ch2 = ch3;
//指针 右边的地址拷贝给了指针
char *ch4 = "abc";
定义一个字符指针
char *ch4 = “abc”;
在代码段申请了4个连续的字节的内存空间用以存储字符串"abc",将首地址赋值给ch4,即将字符’a’的内存地址赋值给ch4。不可更改,只能通过指针来访问该字符串。
建议 写成 const char *ch4 = “abc”;否则存储的内容可能被修改乱码。
指针运行速度快,对内存理解不深刻的话,容易乱套。 易造成内存溢出。
定义一个字符数组
char ch4[] = {‘a’, ‘b’, ‘c’,’\0’};
char ch4[] = “abc”;
在栈内存中定义了一个字符数组ch4,有4个元素依次为’a’, ‘b’, ‘c’,’\0’;
章节14-16 结构体-面向对象前奏
课题73_初识结构
结构:一种构造数据类型,由若干数据项组合而成
struct StructName
{
//结构成员
DataType var1;
DataType var2;
}
举例说明//struct Hero 相当于一个数据类型
#include <stdio.h>
#include <stdlib.h>
struct Hero
{
char name[50];
int age;
};
int main()
{
struct Hero yjy;
strcpy(yjy.name, "yujingya");//如果是使用scanf 要molloc
yjy.age = 23;
printf("%s\t%d\n",yjy.name,yjy.age);
return 0;
}
注意
1.结构定义不预留内存
2.一般放在程序开始部分(头文件声明之后)
3.结构定义仅用来描述结构的形式,使用结构需要声明结构变量
课题74_使用结构
结构体的存储方式和数组一样,结构体里面只有属性,可以用{12,123}的方式赋值。
可以定义结构类型的同时,声明结构变量?
struct Hero
{
char name[50];
int age;
}yjy,hcy;
直接声明结构变量?
struct//直接声明结构变量
{
char name[50];
int age;
}yjy,hcy;
嵌套结构
结构A调用结构B,访问属性的时候可以多层访问
课题75 76_指向结构的指针
一个指针指向结构时,称为结构指针变量,
结构指针变量中的值是所指向结构变量的首地址
定义:
struct 结构名称 *结构指针变量名 = &实体;
访问:
(*结构指针变量).成员变量名
结构指针变量->成员变量名
动态录入用molloc
定义结构体的时候可以使用typedef 简化结构体的使用(宏定义),后面用的时候可以不写struct。
typedef struct _hero
{
int id;
char * name;
char sex;
}Hero;
//使用的时候
Hero heros[5];//相当于定义了一个新的类型,Hero
void InputHero()
{
int i;
for(i = 0; i<1; i++)
{
heros[i].id = i+1;
heros[i].name = (char*)malloc(50);//动态录入
scanf("%s",heros[i].name);
scanf("%c",&heros[i].sex);
fflush(stdin);//良好的习惯:录入字符后记得清空缓冲区
}
}
main.c中使用外部变量声明
extern Hero heros[100];
告诉编译器我这个变量将在其他外部c文件中定义,我这里只是在外部用它。编译器就不给他分配内存空间,而等到真正遇到变量定义的时候再给他分配内存空间。?C全局变量与外部变量
课题77_初识结构数组
结构数组:元素为结构类型的数组成为结构数组
struct Role
{
char * name;
int age;
char * job;
char * skill;
}roles[25];
//
struct Role roles[25];
getchar() 需要录入的时候录入回车
**getch()**录入的时候不需要输入回车
课题78 79_向函数传递结构的信息
结构作为函数参数的三种方式:
1.传递结构成员
2.传递结构
优点:函数处理的是原始数据的副本,保护了原始数据
缺点:老版不支持;传递结构浪费时间和存储空间
一般用来处理小型结构数据
3.传递结构的地址
优点:程序的执行速度快,效率高
缺点:无法保护数据 ,函数中的操作有可能会意外影响原结构的数据(所以用const)
常用此方案
传递结构成员:
//信用卡账户
struct Account
{
char * bankName;//银行名称
char * userName;//用户名称
double limit;//账户额度
double billAmount;//当月账单
};
//计算并返回当月应还款
double GetRepayment(double m1,double m2)
{
return m1 - m2;
}
struct Account zsAcc;
zsAcc.bankName = "招商银行";
zsAcc.userName = "华晨宇";
zsAcc.limit = 50000;
zsAcc.billAmount = 35000;
double result = GetRepayment(zsAcc.limit,zsAcc.billAmount);
printf("本月应还款:%.2lf\n",result);
传递结构:
//信用卡账户
struct Account
{
char * bankName;//银行名称
char * userName;//用户名称
double limit;//账户额度
double billAmount;//当月账单
};
//计算并返回当月应还款
double GetRepayment(struct Account account)
{
return account.limit - account.billAmount;
}//该方案传递结构变量时,是赋值整个结构变量的值道函数中-效率低
传递结构指针:
//信用卡账户
struct Account
{
char * bankName;//银行名称
char * userName;//用户名称
double limit;//账户额度
double billAmount;//当月账单
};
//计算并返回当月应还款
double GetRepayment(const struct Account *account)
{
return account->limit - account->billAmount;
}//相当于递名片,传递指针比较危险,可以任意修改所以+const,这样指针内容只能被调用,而不能被修改,更加安全。
struct Account zsAcc;
zsAcc.bankName = "招商银行";
zsAcc.userName = "华晨宇";
zsAcc.limit = 50000;
zsAcc.billAmount = 35000;
double result = GetRepayment(&zsAcc);
printf("本月应还款:%.2lf\n",result);
typedef
可以为某一类型自定义名称
typedef unsigend char Byte;
Byte btValue1;
typedef struct [hero]
{
char * name;
int age;
char * job;
char * skill;
}Hero;
//使用
Hero hero = {"佟湘玉",35,"掌柜的","额滴神呐"};
课时80_搭建商城系统结构
**题目:**模拟实现道具店购物功能
1.商店暂时只支持一种类型的商品
2.商品具备名称、价格、库存等属性
3.模拟玩家购买游戏道具
3.1选择购买的道具
3.2同意交易后扣除相应的游戏币
3.3对应商品库存-1
3.4玩家背包中增加商品或该商品的数量
结构:
1.商品结构-名称、单价、库存量、描述
2.玩家结构-编号、名称、密码、金钱、背包
3.背包结构-玩家编号、商品[10]、道具数量、最大道具数
人肉码出来的代码?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
模拟实现道具店购物功能
结构:
1.商品结构-名称、单价、库存量、描述
2.玩家结构-编号、名称、密码、金钱、背包
3.背包结构-玩家编号、商品[10]、道具数量、最大道具数
模拟玩家购买游戏道具
1择购买的道具
2同意交易后扣除相应的游戏币
3对应商品库存-1
4玩家背包中增加商品或该商品的数量
*/
/* 商品结构 */
typedef struct _prop{
int id;
char name[50]; //道具名称
double price; //道具单价
int stock; //库存量:如果过在背包中,表示此道具的叠加数量
char desc[200]; //道具的功能描述
}Prop;
/* 背包结构 */
typedef struct _bag{
int playerId; //所属玩家的编号
int count; //当前背包中国,道具的数量
int max; //当前背包的插槽总数- 插槽总数可以让用户用rmb购买
Prop props[8]; //当前背包中的道具数组
}Bag;
/* 玩家结构 */
typedef struct _player{
int id; //玩家编号
char name[50]; //用户名/昵称
char pass[50]; //当前背包的插槽总数
Bag bag; //玩家背包
double gold; //玩家金币-人性化显示:100000转换成银币、金币显示
double sysee; //元宝数量
}Player;
Prop *props;
Player *players;
int propsCount ;
int playerCount ;
void Init();
void ShowProps();
void ShowPlayers();
void Trade(Player *player,int propId);
int main()
{
//初始化游戏数据
Init();
printf("\n************交易前****************\n");
//2、打印游戏数据
ShowProps();
ShowPlayers();
Trade(&players[0],3);
printf("\n************交易后****************\n");
ShowProps();
ShowPlayers();
return 0;
}
/**
* 交易函数
* 参数1:参与交易的玩家指针-为了方便修改玩家交易后的金币数
* 参数2:玩家购买的商品id
*/
void Trade(Player *player,int propId)
{
int i;
//需要判断:商品的库存,玩家的余额够不够,玩家背包空间
Prop *tradeProp;//要购买的商品指针
for(i = 0; i<propsCount; i++)
{
if(propId == props[i].id){
tradeProp = &props[i];//tradeProp = props + i;
break;
}
}
if(tradeProp->stock<=0)
{
printf("地主家没有余粮啦!\n");
return;
}
if(player->gold < tradeProp->price)
{
printf("余额不足!\n");
return;
}
if(player->bag.count >= player->bag.max && player->bag.count!=0)
{
printf("背包空间不足!\n");
return;
}
//满足交易条件,执行交易操作
//1.商品库存-1
tradeProp->stock--;
//2.玩家金币-商品单价
player->gold -= tradeProp->price;
//3.玩家背包道具增加
//判断玩家背包中是否已有该商品
//如果有该商品,背包中的该商品总数+1
for(i = 0; i <player->bag.count; i++)
{
//如果要购买的id跟背包中某个商品id相同
if(propId == player->bag.props[i].id)
{
player->bag.props[i].stock++;
break;
}
}
if(i == player->bag.count)//如果没有该商品,该商品添加到背包中
{
//向背包中创建一个商品-复制一份要交易的商品信息到背包中
int newIndex = player->bag.count;
player->bag.props[newIndex].id = tradeProp->id;
player->bag.props[newIndex].price = tradeProp->price;
player->bag.props[newIndex].stock = 1;
strcpy(player->bag.props[newIndex].name, tradeProp->name);
strcpy(player->bag.props[newIndex].desc, tradeProp->desc);
player->bag.count++;
}
}
void Init()
{
//1、初始化数据
static Prop propArray[] = {
{1, "高倍望远镜", 300, 10, "演唱会必备!"},
{2, "超亮荧光棒", 50, 8, "最美红海"},
{3, "应援横幅", 20, 7, "为hcy疯狂打call"},
{4, "门票", 1280, 6, "相约11.2"},
{5, "直升机", 10000, 2, "6的飞起"},
};
propsCount = sizeof(propArray) / sizeof(Prop);
props = propArray;//设定指针的指向
static Player playerArray[] = {
{1, "绒绒", "8023", .gold=50000, .bag.max=8},
{2, "炸炸", "8023", .gold=150000, .bag.max=8},
{3, "大哥", "8023", .gold=500000, .bag.max=8},
{4, "壳儿", "8023", .gold=1150000, .bag.max=8}
};
playerCount = 4;
players = playerArray;
}
void ShowProps()
{
int i;
if(props == NULL) return;
printf("%-8s%-16s%-16s%-8s商品介绍\n","商品","名称","单价","库存");
for(i = 0; i < propsCount; i++)
{
printf("%-5d\t%-14s\t%-10.2lf\t%d\t%s\n",props[i].id, props[i].name, props[i].price, props[i].stock, props[i].desc);
}
}
void ShowPlayers()
{
int i,j;
if(players == NULL) return;
printf("=====================================================\n");
printf("%-8s%-16s%-16s\n","玩家","名称","金币");
for(i = 0; i < playerCount; i++)
{
printf("%-5d\t%-14s\t%-10.2lf\n",players[i].id, players[i].name,players[i].gold);
//printf("玩家的背包数据如下:\n");
for(j = 0;j <players[i].bag.count;j++)
{
printf("\t%s\t%d\t",players[i].bag.props[j].name, players[i].bag.props[j].stock);
}
printf("\n");
}
}
可以通过只想结构的指针访问结构成员
常用形式为:结构指针变量->成员名