[要素察觉]C语言七讲:结构体及C++引用讲解
admin
2024-01-22 02:12:53
0

[要素察觉]C语言七讲:结构体及C++引用讲解

  • 1. 结构体 - 结构体对齐 - 结构体数组
    • 1 结构体的定义、初始化、结构体数组
      • 【例1.1】结构体的scanf读取和输出。
      • 【例1.2】结构体数组
    • 2 结构体对齐
      • 【例】结构体对齐
  • 2. 结构体指针与typedef的使用
    • 1 ==结构体指针==
      • 【例1.1】结构体指针的使用
    • 2 typedef的使用
      • 【例2.1】typedef的使用
  • 3. C++引用的讲解
    • 1 C++的引用讲解
      • 【例1.1】在子函数内修改主函数的普通变量(C++)
      • 【例1.2】在子函数内修改主函数的普通变量(纯C)
      • 【例1.3】子函数内修改主函数的一级指针变量(==重要==)
      • 【例1.4】子函数内修改主函数的一级指针变量(纯C)
    • 2 C++的布尔类型
      • 【例2.1】布尔类型也是有值的
  • 总结
    • 1.1
    • 1.2
    • 2.1
    • 2.2
    • 3.1
    • 3.2


1. 结构体 - 结构体对齐 - 结构体数组

1 结构体的定义、初始化、结构体数组

  • 有时候需要将不同类型的数据组合为一个整体,以便于引用。

例如,一名学生有学号、姓名、性别、年龄、地址等属性,如果针对学生的学号、姓名、年龄等都单独定义一个变量,那么在有多名学生时,变量就难以分清。

  • C语言提供结构体来管理不同类型的数据组合。
  • 声明一个结构体类型的一般形式为:
struct 结构体名{成员列表};

例如

struct student{int num;char name[20];char sex;int age;float score;char addr[30];};

先声明结构体类型,再定义变量名。例如,

struct student student1, student2;
  • 结构体类型声明,注意最后一定要加分号。
  • 变量名和结构体名字不能一样。

【例1.1】结构体的scanf读取和输出。

#include struct student
{int num;char name[20];char sex;int age;float score;char addr[30];
};//结构体类型声明,注意最后一定要加分号int main()
{struct student s = { 1001, "lele", 'M', 20,85.4, "shenzhen" };//定义及初始化printf("%d %s %c %d %f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);//混合读取,%c不会忽略任何字符scanf("%d%s %c%d%f%s",&s.num, s.name, &s.sex, &s.age, &s.score, s.addr);//数组名就是首地址struct student sarr[3];return 0;
}

注意

  • 因为如果结构体变量已经定义,那么只能对他的每个成员单独赋值,如s.sum = 1003。

  • 结构体输出必须单独访问内部的每一个成员。
     
    printf不可以直接输出结构体,需要逐个成员访问,采用结构体变量名.成员名的形式来访问结构体成员。
    例如用s.num访问学号。

  • printf中的%类型要与各成员匹配。

  • 字符型数据(%c)不会忽略空格,如果要读取字符型数据,那么就要在待读取的字符数据和其他数据之间加入空格。

【例1.2】结构体数组

#include struct student
{int num;char name[20];char sex;int age;float score;char addr[30];
};int main()
{struct student sarr[3];//定义结构体数组变量 - 一个数组中有三个结构体int i;for (i = 0; i < 3; i++)//结构体数组输入{scanf("%d%s %c%d%f%s", &s.num, s.name, &s.sex, &s.age, &s.score, s.addr);}for (i = 0; i < 3; i++)//结构体数组输出{printf("%d %s %c %d %5.2f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);}return 0;
}

2 结构体对齐

结构体的大小必须是其最大成员的整数倍!

  • 结构体对齐是为了cpu高效读取内存上的数据。

【例】结构体对齐

#include 
struct student_type1
{double score;//double是一种浮点类型,8个字节,浮点分为float和double,记住有这两种即可short age; //2 - 8
};//16struct student_type1
{double score;//8int height;//4short age;//2
};//16
//如果两个小成员(4+2)小于最大成员(8),可以结合在一起。
//2+4 < 8,int和short占8个字节struct student_type1
{int height;//4char sex;//1short age;//2
};//8
//1+2 < 4,char和short占4个字节//结构体对齐 - 结构体占多大空间
int main()
{struct student_type1 s1;struct student_type2 s2;struct student_type3 s3;printf("s1 size=%d\n", sizeof(s1));printf("s2 size=%d\n", sizeof(s2));printf("s3 size=%d\n", sizeof(s3));return 0;
}

2. 结构体指针与typedef的使用

1 结构体指针

  • 一个结构体变量的指针就是该变量所占据的内存段的起始地址。
  • 可以设置一个指针变量,用它指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。
  • 指针变量也可以用来指向结构体数组中的元素,从而能够通过结构体指针快速访问结构体内的每个成员。

【例1.1】结构体指针的使用

#include struct student
{int num;char name[20];char sex;
};int main()
{struct student s = { 1001,"wangle",'M' };struct student sarr[3] = { 1001,"lilei",'M',1005,"zhangsan",'M',1007,"lili,'F" };printf("%d\n",sizeof(s));//28struct student *p;//定义结构体指针变量int num;p = &s;//拿到起始地址赋给结构体指针printf("%d %s %c\n", p->num, p->name, p->sex);//对象指针->成员名p = sarr;//结构体数组 - 数组名存的就是数组的起始地址 - 等价于p = &sarr[0]//对象.成员名printf("%d %s %c\n", (*p).num, (*p).name, (*p).sex);//方式一获取成员 - 加括号成为整体 - 取值*的优先级没有.的优先级高printf("%d %s %c\n", p->num, p->name, p->sex);//方式二获取成员 - 这个方式更好printf("-----------------------------------------\n");p = p + 1;printf("%d %s %c\n", p->num, p->name, p->sex);return 0;
}
  • p就是一个结构体指针,可以对结构体s取地址并赋给p。借助成员选择操作符,就可以通过p访问结构体的每个成员,然后进行打印。
  • 数组名中存储的是数据的首地址,所以可以将sarr赋给p。
  • 使用(*p).num要加括号,因为“.”成员选择的优先级高于“*”(取值)运算符,所以必须加括号。
  • 对象.成员名
    对象指针->成员名
    方式二更好

2 typedef的使用

高效

  • 使用typedef声明新的类型名来代替已有的类型名。

【例2.1】typedef的使用

#include //原写法
//struct student 
//{
//	int num;
//	char name[20];
//	char sex;
//};//typedef的使用 - 起别名
// stu 等价于 struct student, pstu 等价于 struct student*
//结构体指针
typedef struct student
{int num;char name[20];char sex;
}stu,*pstu; //别名 - 结构体/结构体指针typedef int INTEGER;//特定的地方使用 - 给int起别名int main()
{//struct student s = { 0 };//原写法stu s = { 1001,"wangle",'M' };//别名stu* p = &s;//定义了一个结构体指针变量pstu p1 = &s;INTEGER i = 10;printf("i=%d,p->num=%d\n", i, p->num);return 0;
}
  • 使用stu定义结构体变量和使用struct student定义结构体变量是等价的。
  • 使用INTEGER定义变量i和使用int定义变量i是等价的。
  • pstu等价于struct student*,所以p是结构体指针变量。

3. C++引用的讲解

1 C++的引用讲解

  • 对于C++,新建源文件时,以.cpp后缀结尾。
  • C++的引用很便捷。

例子:

int a;
void modifynum(int &b)
{b = b + 1;
}
//调用:modifynum(a)int *p = NULL;
void modify_pointer(int *&p)
{......p = q;......
}
//调用:modify_pointer(p)
  • 在修改函数外某一变量时,使用了引用后,在子函数内的操作和函数外操作手法一致,效率更高。

【例1.1】在子函数内修改主函数的普通变量(C++)

#include //兼容c的头文件//在子函数中修改主函数中变量的值,使用引用;不需要修改,不用。
void modify_num(int &b)//引用 - 形参中写&,要称为引用
{b = b + 1;
}//C++的引用的讲解
//在子函数内修改主函数的普通变量的值
int main()
{int a = 10;modify_num(a);printf("after modify_num a = %d\n", a);return 0;
}

将上面的代码改为纯C语言:

【例1.2】在子函数内修改主函数的普通变量(纯C)

#include void modify_num(int *b)
{*b = *b + 1;
}int main()
{int a = 10;modify_num(&a);printf("after modify_num a = %d\n", a);return 0;
}
  • 引用的效率更高
  • 在子函数中修改主函数中变量的值,使用引用;不需要修改,就不用。

【例1.3】子函数内修改主函数的一级指针变量(重要

#include void modify_pointer(int *&p, int *q)//引用必须和变量紧邻
{p = q;
}int main()
{int *p = NULL;//0int i = 10;int *q = &i;modify_pointer(p, q);printf("after modify_pointer *p = %d\n", *p);return 0;//当进程已结束,退出代码不为0,那么代表进程异常结束
}
  • 引用必须和变量紧邻。
  • 当进程已结束,退出代码不为0,那么代表进程异常结束。

【例1.4】子函数内修改主函数的一级指针变量(纯C)

#include 
void modify_pointer(int **p, int *q)//相对于C++这里是int **p;
{*p = q;//这里的写法和例1.3中的是非常类似的
}int main()
{int *p = NULL;int i = 10;int *q = &i;modify_pointer(&p, q);//相对于C++这里是&pprintf("after modify_pointer *p = %d\n", *p);return 0;
}

纯C使用了二级指针。

2 C++的布尔类型

  • 布尔类型是C++的,有true和false。

【例2.1】布尔类型也是有值的

//设置布尔值的好处是提升了代码的可阅读性
int main()
{bool a = true;bool b = false;printf("a = %d, b = %d\n", a, b);//ture = 1; false = 0return 0;
}

总结

1.1

  • 结构体类型声明,注意最后一定要加分号。
  • 变量名和结构体名字不能一样。
  • 因为如果结构体变量已经定义,那么只能对他的每个成员单独赋值,如s.sum = 1003。
  • 结构体输出必须单独访问内部的每一个成员。
  • printf中的%类型要与各成员匹配。
  • 字符型数据(%c)不会忽略空格,如果要读取字符型数据,那么就要在待读取的字符数据和其他数据之间加入空格。

1.2

  • 一个结构体变量的指针就是该变量所占据的内存段的起始地址。
  • 可以设置一个指针变量,用它指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。
  • 指针变量也可以用来指向结构体数组中的元素,从而能够通过结构体指针快速访问结构体内的每个成员。

2.1

  • p就是一个结构体指针,可以对结构体s取地址并赋给p。借助成员选择操作符,就可以通过p访问结构体的每个成员,然后进行打印。
  • 数组名中存储的是数据的首地址,所以可以将sarr赋给p。
  • 使用(*p).num要加括号,因为“.”成员选择的优先级高于“*”(取值)运算符,所以必须加括号。

2.2

  • 使用typedef声明新的类型名来代替已有的类型名。
  • 使用stu定义结构体变量和使用struct student定义结构体变量是等价的。
  • 使用INTEGER定义变量i和使用int定义变量i是等价的。
  • pstu等价于struct student*,所以p是结构体指针变量。

3.1

  • 对于C++,新建源文件时,以.cpp后缀结尾。
  • C++的引用很便捷。
  • 在修改函数外某一变量时,使用了引用后,在子函数内的操作和函数外操作手法一致,效率更高。
  • 在子函数中修改主函数中变量的值,使用引用;不需要修改,就不用。
  • 引用必须和变量紧邻。
  • 当进程已结束,退出代码不为0,那么代表进程异常结束。

3.2

  • 布尔类型是C++的,有true和false。

相关内容

热门资讯

原创 特... 特朗普政府试图将委内瑞拉的石油资源纳入美国巨头的囊中,但事与愿违。这场旨在促成巨额投资的白宫会议,最...
原创 谢... 谢尔盖·布林:科技巨擘的崛起与慈善之路 2026年1月12日,一个值得铭记的日子。这一天,在Alph...
马士基宣布恢复红海航线 航运业... 财联社1月16日讯(编辑 牛占林)丹麦航运巨头马士基(Maersk)当地时间周四表示,在该地区安全形...
贵金属价格上涨能否持续 回顾2025年大类资产表现,以黄金、白银、铂族金属为代表的贵金属板块价格一路狂飙,令全球投资者印象深...
手握金条无处安放?银行保管箱“... 本报(chinatimes.net.cn)记者付乐 见习记者 林佳茹 北京报道 “现在网点暂时没有空...
雷军直播再谈“反小字营销”!新... 1月15日晚,小米创办人、董事长兼CEO雷军在直播中再度聚焦“小字营销”问题,明确表达小米反对该行业...
重庆今年首只新股至信股份上市 ... 1月15日,重庆至信实业股份有限公司(以下简称“至信股份”)在上海证券交易所主板敲锣上市,成为今年A...
创历史新高!2025年我国外汇... 国家外汇管理局1月15日发布数据显示,2025年,我国外汇市场交易量达42.6万亿美元,企业外汇套期...
跨境电商运营:2026全球瑜伽... 今天分享的是:跨境电商运营:2026全球瑜伽服市场洞察报告 报告共计:41页 《2026全球瑜伽服市...
中文在线涨势“刹车”,上市以来... 来源:市场资讯 来源:国际金融报 1月15日,连续多日因“狂飙”行情被称为新“易中天”之一的中文在线...
原创 1... 写在文章前的声明:在本文之前的说明:本文中所列的投资信息,只是一个对基金资产净值进行排行的客观描述,...
湾财晚报| 商业用房首付比例降... 编辑 | 子衿 商业用房首付比例降至30% 今日,商办地产市场迎来重磅利好。 中国人民银行新闻发言人...
全年26亿!这些银行“喜提”罚... 过去一年,监管“长牙带刺、有棱有角”的态度一以贯之,驱动银行从根源上提升合规能力,强化内控管理。 企...
业绩拐点已现?金沃股份预计去年... 公司于今日晚间发布公告,2025年,公司在手订单情况良好,预计实现营业收入12.4-12.5亿元,同...
监管批复!郑荣波就任东亚银行珠... 2026年1月15日,根据国家金融监督管理总局消息,《关于核准郑荣波东亚银行(中国)有限公司珠海分行...
格力电器,近56亿元“大红包”... 1月15日晚,格力电器披露2025年中期权益分派实施公告。 根据方案,格力电器拟以公司现有总股本剔...
新技术助力提高IVF成功率,女... 打破生育瓶颈:新技术或助提高IVF成功率 想象一下,经历了数次试管婴儿(IVF)治疗的女性,心中满是...
卖“未来”换喘息:一品红主业失... 一品红(300723.SZ)再次向市场递交了一份亏损的成绩单。 1月14日发布的业绩预告显示,一品红...
央行:下调各类结构性货币政策工... 文、摄影/刘佳 1月15日,人民银行新闻发言人、副行长邹澜在国新办新闻发布会上表示,根据当前经济金融...
锂电大牛股,董事长等三人收到警... 2025年股价涨幅高达429.42%的锂电大牛股天际股份,1月15日晚发布扭亏为盈的业绩预告,同时“...