复合数据类型

声明一个结构体类型的一般形式为:

struct 结构体名{j结构体所包含的成员变量}

struct stu{

char name[20];//姓名

int num;//学号

int age;//年龄

char grop;、、所在学习小组

}

stu 为结构体名,它包含了5个成员,分别是 name,num,age,group,score

定义结构体类型变量:

struct stu s1,s2;

struct stu{

char name[20];//姓名

int num;//学号

int age;//年龄

char group;//所在学习小组

float score;//成绩

}s1,s2;

struct {

char name[20];

int num;

int age;

char group;

float score;

}s1,s2;

结构体变量赋值与使用

struct stu stu1 = {"Tom", 12,18,'A',136.5};

struct stu stu1 = {.name="Tom”,.num= 12, .age=18,.group='A',.score=136.5};


struct stu {

char *name;

int num;

int age;

char group;

float score;

}s1 = {"Tom",12,18,'A',136.5};

访问结构体成员变量使用点号操作符·

stu1.name= "Tom";

stu1.num=12;

stu1.age=18;

stu1.group='A';

stu1.score=136.5;

结构体内存对齐模式:

内存对齐初步

数据项只能存储在地址是数据项大小的整数倍的内存位置上

例如int类型占用4个字节,地址只能在0,4,8等位置上。

操作系统的默认对齐系数

每个操作系统都有自己的默认内存对齐系统,如果是新版本的操作系统,默认对齐系统一般都是8,因为操作系统定义的最大类型存储单元就是8个字节,例如long long,不存在超过8个字节的类型(例如int是4,char是1,long在32为编译时是4,64位编译时是8)。当操作系统的默认对齐系数与内存对齐理论产生冲突时,以操作系统的对齐系数为基准。

例如:

假设操作系统的默认对齐系数是4,那么对与long long这个类型的变量就不满足第一节所说的,也就是说long long这种结构,可以存储在被4整除的位置上,也可以存储在被8整除的位置上。

可以通过#pragmatic pack()语句修改操作系统的默认对齐系数,编写程序的时候不建议修改默认对齐系数。

内存对齐产生的影响

内存对齐是操作系统为了快速访问内存而采取的一种策略,简单来说,就是为了放置变量的二次访问。操作系统在访问内存时,每次读取一定的长度(这个长度就是操作系统的默认对齐系数,或者是默认对齐系数的整数倍)。如果没有内存对齐时,为了读取一个变量是,会产生总线的二次访问。

例如假设没有内存对齐(默认对齐系数是8),结构体xx的变量位置会出现如下情况:

structxx{

char b;  //oxffbff5e8

int a;    //oxffbff5e9

int c;//oxffbff5ed

char d;//oxffbff5f1
};

操作系统先读取oxffbff5e8-oxffbff5ef的内存,然后在读取oxffbff5fo-oxffbff5f8的内存,为了获得值c,就需要将两组内存合并,进行整合,这样严重降低了内存的访问效率。(这就涉及到了老生常谈的问题,空间和效率那个更重要?)。

这样大家就能理解为什么结构体的第一变量,不管类型如何,都是能被8整除的吧(因为访问内存是从8的整数倍开始的,为了增加读取的效率)!

define 宏函数

#define SUM(a,b)  ((a)+(b))

#define MIN(a,b) ((a)<(b)?(a):(b)

条件编译ifdef #ifndef...#else...#endif

#ifndef标识符

程序段1

#else

程序段2

#endif

与上一种形式的区别是ifdef改为ifndef。它的功能是:如果标识符未被#define命令定义过,则对程序段1进行编译;否则对程序2进行编译。这与第一种形式的功能正好相反

static 修饰局部变量

在局部静态变量前面加上关键字static,该局部变量便成了静态局部变量。静态局部变量有以下特点:

(1)该变量在全局数据区分配内存

(2)如果不显示初始化,那么将被隐式初始化为0

(3)它始终驻留在全局数据区,直到程序运行结束

(4)其作用域为局部作用域,当定义它的函数块语句块结束时,其作用域随之结束。

static修饰全局变量

在全局变量前面加上关键字static,该全局变量变成了全局静态变量。

全局静态变量有以下特点:

(1)在全局数据区分配内存

(2)如果没有初始化,其默认值为0

(3)该变量在本文件内从定义开始到文件结束可见,即只能在本文件内使用

const修饰一般变量

一般变量是指简单类型的只读变量。这种只读变量在定义时,修饰符const可以用在类型说明符前,也可以用在类型说明符后。例如:

int const i=2;或const int i=2;

定义或说明一个只读数组可采用如下格式:

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

const int *p;  //p可变,p指向的对象不可变

int const * p;  //p可变,p指向的对象不可变

int * const p;//  p不可变,p指向的对象可变

int *const p;   //p不可变,p指向的对象可变

const int * const p;    //指针p和p指向的对象都不可变


这里给出一个记忆和理解的方法:

先忽略类型名(编译器解析的时候也是忽略类型名),我们看const离哪个近,“近水楼台先得月”,离谁近就修饰谁。

const (int) *p  //const 修饰*p,p是指针,*p是指针指向的对象,不可变




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值