Linux 基础---记录五之结构体篇

为什么要有结构

char -128+127

short -32768+32767

int

long

学生:

int num1;

char name1[20];

int score1;

int num2;

char name2[20];

int score2;

int num3;

char name3[20];

int score3;

结构体定义

一般声明

struct  结构体名

{

成员列表------《可以为任意数据类型》

int a;

int *p ;

void(*p)(void);

char b[200];

struct  ---等

};

嵌套结构体声明

一般嵌套

1.

struct A{
    int a;
    int b;
};
struct B{
    int b;
    struct A a;
};


2.

/*
struct A{
    int a;
    struct A b;
};*/ 错误定义
struct A{
    int a;
    struct A *p;
}; //声明是对的;


互相嵌套

/*
struct  A{
    int a;
    struct B b;
};
struct  B{
    int b;
    struct A a;
};*/错误的声明方式

struct  A{
    int a;
    struct B *b;
};
struct  B{
    int b;
    struct A *a;
};

定义

1.

struct  stu{
    int num;
    char name[20];
    int score;
};//频率非常高
struct stu a;

2.

struct  stu{
    int num;
    char name[20];
    int score;
}a; //会见到
struct stu b;

3.

struct  {
    int num;
    char name[20];
    int score;
    int age;
}a; //不常用

4.

typedef struct  stu{
    int num;
    char name[20];
    int score;
}STU,*PSTU; //会见到
STU a;    //定义了一个srtuct stu结构体变量 与 struct stu a等价
PSTU P;  //定义了一个指向struct stu 结构变量的指针  与struct stu *p等价

5.结构体数组

struct  stu{
    int num;
    char name[20];
    int score;
}a; //会见到
struct stu b[10];//int a[10];

使用

定义 及 初始化://int a=3;

//指定初始化:往往应用在结构体成员非常多的情况

struct stu a={   //int a=3;
    .num =1,
    .name ="xiaohe",
    .score = 100,
 };

 

 

struct stu a={   //int a=3;
    num:1,
    name:"xiaohe",
    score:100,
 };

//顺序初始化:一般成员非常少的情况下

struct stu a={   //int a=3;
    1,
    "xiaohe",
    100,
 };

//**数组初始化

int a[]={1,2,3,4,5};

int a[5]={1,2,3,4};//未初始化的空间会被编译器初始化成零

int a[5]={[0]=1,[2]=3};

如果未初始化:

全局变量:会被编译器初始化成0

局部变量:里面将就内存的值,随机值

//****

struct  stu{
    int num;
    char name[20];
    int score;
}a; //会见到

struct stu b[2]={
    {1,"xiaohe",100},
    {2, "xiaohehe",101},
};

struct stu b[2]={
    [0]={1,"xiaohe",100},
    [1]={
        .num = 2, 
        .name = "xiaohehe",
        .score =101
    },
};

b[0].num

b[1].num

赋值

      //int a ;a =3

struct  stu{
    int num;
    char name[20];
    int score;
};

/*
struct stu b;
b={ //error,只能在初始化使用
    .num = 2, 
    .name = "xiaohehe",
    .score =101
}*/

1.单个赋值

struct stu b;
b.num = 1;
//b.name = "xiaohe" //error  //char s[10];s="niahoa" ---error
strcpy(b.name,"xiaohe")
b.score = 100;

2.整体赋值

1.结构体变量b = 结构体变量a 

struct stu a={   //int a=3;
    .num =1,
    .name ="xiaohe",
    .score = 100,
};
struct stu b = a;

2.内存搬移函数

memcpy(void *dest, const void *src, size_t n);

memcpy(&b,&a,sizeof(struct stu));

操作

1.单个操作(直接操作)

变量名.成员名----------得到的是成员名的本身属性

a.num 

a.name

1.结构体指针

                (内存:线性唯一,没有数据类型:程序猿按照数据类型的方式去操作内存)

指针:1.地址,2操作方式

定义:

struct  stu{
    int num;
    char name[20];
    int score;
};

struct stu *p; ----一个指针,指向了一个内存地址,按照结构体的方式操作内存

struct stu a={   //int a=3;
    .num =1,
    .name ="xiaohe",
    .score = 100,
}
p=&a;

通过指针间接操作结构体空间:

指针名->成员名   :得到的是成员的本身属性

(*指针名).成员名 :同上,等价

2.结构体指针作函数参数:程序猿的必杀技

同其他指针作参数一样,哦也

结构体之嵌套define

struct A{
    int a;
    #define M 3
    #define  M1  4 
};

结论:无任何意义, 可能:a的取值选项

结构体之字节对齐(结构体之五星重点)

1.结构体之内对齐

                       (作用:决定了每个成员的存放地址)

每个成员对齐值 与 系统对齐值比较:   取最小的那个

成员对齐值:            系统的对齐值:默认是4  ,可以修改 #pragma pack(4) ----数字就是对齐值,以2的次方改

char   1        -------1 ,4  -----1   addr%1 ==0

short  2        -------2 , 4  -----2   addr%2 ==0

int    4        -------4 , 4  -----4   addr%4 ==0 

2.结构体之外对齐

每个成员比较后的对齐值中:取最大的

1

4        4

1    

3.结构体之地址对齐

结构体外对齐值 与系统地址对齐值相比(默认为4 ,可修改 __attribute((aligned(4))) 同上):取最大的

注意: ARM 的 cpu 每次取值是从地址 addr 取值,其中 addr 满足 addr%4 == 0;

1结构体之内对齐  ----针对结构体内的对齐

2结构体之外对齐  ----

3结构体之地址对齐---- 2、3是针对万一有结构数组的情况,所以也得满足

注意:

情况一:

结构体没有使用 attrribute时,对齐方式由1和2来确定;

1来确定每个成员存放的位置;

2来确定下一个结构体存放的位置;

情况二:

结构体使用了attribute时,对齐方式由1,2,3,共同确定;

1来确定每个成员存放的位置;

2和3来确定下一个结构体存放的位置;

修改结构体内成员对齐的默认:#program park(4)

修改结构体外对齐2的n次方的默认:__attribuate((aligned (4)))


转载于:https://my.oschina.net/fengyeshangqing/blog/347516

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值