和结构体有关的知识点

       C++中,除了基本的数据类型(如char、int、float、double等),还有结构体类型(structure)、共用体类型(union)、枚举类型(enumeration)、类类型(class )等,供用户灵活使用。但是在面试时,和C语言有关的知识点涉及的比较多,其中结构体经常会出现,最常见的就是问题就是这个结构占多少个字节。

1、结构体被编译后实际占用内存的大小

struct StudentType      //声明一个结构体类型StudentType
{
int        num;               //int型变量num,占4个字节
char     name[20];    //char型数组name,占20个字节
char     sex;             //char型变量sex,占1个字节
int        age;                /int型变量age,占4个字节
float     score;          //float型变量,占4个字节
char     addr[30];     //char型数组name,占30个字节
};//注意:最后有一个分号
struct StudentType student1, student2;
以上定义了student1和student2为StudentType的变量,即它们具有StudentType类型的结构。在定义了结构体变量后,系统就会为之分配内存单元
在理论上,student1和student2在内存中各占63个字节 4+20+1+4+4+30=63。 但是这里需要注意:根据不同编译器,内存存储会有所不同,存储该结构体会按照内存对齐进行相关处理,系统默认对齐系数为4(即按int类型对齐,粗略认识可以认为每相邻两个数据成员存储是大小是4的整数倍。具体计算如下:
struct StudentType      //声明一个结构体类型StudentType
{
int        num;               //int型变量num,理论上占4个字节,根据内存对齐 占4个字节
char     name[20];    //char型数组name,理论上占20个字节,根据内存对齐 占20个字节
char     sex;             //char型变量sex,理论上占1个字节,根据内存对齐 占4个字节
int        age;                /int型变量age,理论上占4个字节,根据内存对齐 占4个字节
float     score;          //float型变量,理论上占4个字节,根据内存对齐 占4个字节
char     addr[30];     //char型数组name,理论上30个字节,根据内存对齐 占32个字节
};
因此, 实际上student1和student2占用内存为:4+20+4+4+4+32=68个字节
不清楚那些面试官为什么喜欢考和编译器有关的知识。
2、指向结构体变量指针引用结构体变量中的成员
#include <iostream>
#include <string>
using namespace std;
int main( )
{
    struct Student   //声明结构体类型student
    { int num;
      char sex;
      float score;
    };
    Student stu;         //定义Student类型的变量stu
    Student *p=&stu;  //定义p为指向Student类型数据的指针变量并指向stu
    stu.num=1000;   //对string变量可以直接赋值
    stu.sex=15;
    stu.score=99.5;
    cout<<stu. num<<″ ″<<″ ″<<stu.sex<<″ ″<< stu.score<<endl;
    cout<<p -> num<<″ ″<<″ ″<<(*p).sex<<″ ″<<  (*p).score<<endl;
    return 0;
}
程序运行结果如下:
1000  15 99.5 (通过结构体变量名引用成员)
1000  15 99.5 (通过指针引用结构体变量中的成员)

3、用结构体变量和指向结构体变量的指针构成链表

链表是一种常见的重要的数据结构 链表有一个“头指针”变量,以head表示,它存放一个地址。该地址指向一个元素。 链表中的每一个元素称为“结点”,每个结点都应包括两个部分:
一是用户需要用的实际数据;
二是下一个结点的地址。
可以看到链表中各元素在内存中的存储单元可以是不连续的。要找某一元素,可以先找到上一个元素,根据它提供的下一元素地址找到下一个元素。 这种链表数据结构,必须利用结构体变量指针才能实现。 可以先声明一个结构体类型,包含两种成员,一种是用户需要用的实际数据,另一种是用来存放下一结点地址的指针变量
例如,可以设计这样一个结构体类型
struct Student
{
    int num;
    float score;
   Student *next; //next指向Student结构体变量
};
其中成员num和score是用户需要用到的数据。next是指针类型的成员,它指向Student类型数据,就是next所在的结构体类型。用这种方法就可以建立链表
每一个结点都属于Student类型,在它的成员next中存放下一个结点的地址,程序设计者不必知道各结点的具体地址,只要保证能将下一个结点的地址放到前一结点的成员next中即可。
下面通过一个例子来说明如何建立和输出一个简单链表 建立一个简单链表,它由3个学生数据的结点组成。输出各结点中的数据。
#define NULL 0
#include <iostream>
struct Student
{
  long num;
  float score;
  struct Student *next;
};
int main( )
{
   Student a,b,c,*head,*p;
   a. num=31001;
   a.score=89.5; //对结点a的num和score成员赋值
   b. num=31003;
   b.score=90; //对结点b的num和score成员赋值
   c. num=31007;
   c.score=85; //对结点c的num和score成员赋值
   head=&a;    //将结点a的起始地址赋给头指针head
   a.next=&b;  //将结点b的起始地址赋给a结点的next成员
    b.next=&c; //将结点c的起始地址赋给b结点的next成员
    c.next=NULL; //结点的next成员不存放其他结点地址
    p=head; //使p指针指向a结点
    do
       {
         cout<<p->num<<″ ″<<p->score<<endl; //输出p指向的结点的数据
         p=p->next; //使p指向下一个结点
       } while (p!=NULL); //输出完c结点后p的值为NULL
    return 0;
}
4、 将一个结构体 变量 中的数据传递给另一个函数
1)、 用结构体 变量 作函数参数
#include <iostream>
#include <string>
using namespace std;
struct Student    //声明结构体类型Student
{ int num;
  float score[3];
};
void print(Student *p); //函数声明
int main( )
{
   
  Student stu;         //定义结构体变量
  stu.num=12345;
  stu.score[0]=67.5;
  stu.score[1]=89;
  stu.score[2]=78.5;
  print(stu); //调用print函数,输出stu各成员的值
  return 0;
}
void print(Student st)
{
   cout<<st.num<<″ ″<<″ ″<<st.score[0]  <<″ ″ <<st.score[1]<<″ ″<<st.score[2]<<endl;
}
运行结果为:
12345 67.5 89 78.5
2)、用指向结构体 变量 的指针作实参
#include <iostream>
#include <string>
using namespace std;
struct Student    //声明结构体类型Student
{ int num;
  float score[3];
}stu={12345,″Li Fung″,67.5,89,78.5};//定义结构体student 变量 stu并赋初值
void print(Student *st); //函数声明
int main( )
{
  print(stu); //调用print函数,输出stu各成员的值
  return 0;
}
void print(Student *p)
{
   cout<<p-> num<<″ ″<<″ ″<<p-> score[0] <<″ ″ <<p-> score[1]<<″ ″<<p-> score[2]<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值