当前位置: 首页 > wzjs >正文

网站开发与设计是什么职业培训机构排名

网站开发与设计是什么,职业培训机构排名,wordpress集中页面地址,查看网站服务器信息C语言已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型还是不够的,假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不行的。 描述一个学生需要名字、年龄、学号、身…

C语言已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型还是不够的,假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不行的。 描述一个学生需要名字、年龄、学号、身高、体重等; 描述一本书需要作者、出版社、定价等。C语言为了解决这个问题,增加了结构体这种自定义的数据类型,让程序员可以自己创造适合的类型。

 1.结构的声明

struct tag
{member-list;
}variable-list;

描述一个学生:

struct Stu
{char name[20];int age;char sex[5];char id[20];
};

1.1 结构体变量的定义和初始化

//代码1:变量的定义
struct Point
{int x;int y;
}p1;     //声明类型的同时定义变量p1
struct Point p2;  //定义结构体变量p2//初始化
struct Point p3 = {10, 20};//代码2
struct Stu
{char name[20];int age;
};
struct Stu s1 = {"zhangsan", 20};//初始化
struct Stu s2 = {.age = 20, .name = "lisa"};//指定顺序初始化//代码3
struct Node
{int data;struct Point p;struct Node* next;
}n1 = {10, {4, 5}, NULL};//结构体嵌套初始化struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

1.2 结构体访问操作符

1.2.1 结构体成员的直接访问

结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。如下:

#include <stdio.h>
struct Point
{int x;int y;
}p = {1, 2};
int main()
{printf("x: %d y: %d\n", p.x, p.y);
return 0;
}

使用方式:结构体变量.成员名 

1.2.2 结构体成员的间接访问

#include <stdio.h>
struct Point
{int x;int y;
};
int main()
{    struct Point p = {3, 4};struct Point *ptr = &p;ptr->x = 10;ptr->y = 20;printf("x: %d y: %d\n", ptr->x, ptr->y);
return 0;
}

使用方法:结构体指针->成员名

综合举例:

#inlcude <stdio.h>
#include <string.h>
struct Stu
{char name[20];int age;
};void print_stu(struct Stu s)
{printf("%s %d\n", s.name, s.age);
}void set_stu(struct Stu* ps)
{strcpy(ps->name, "lisa");ps->age = 20;
}int main()
{struct Stu s = { "zahngsan", 20};print_stu(s);set_ stu(&s);print_stu(s); return 0;
}

1.3结构的特殊声明

在声明结构时,可以不完全声明。

//匿名结构体类型
struct 
{int a;int b;float c;
}x;//匿名结构体指针类型
struct
{int a;char b;float c;
}a[20], *p;

上面的两个结构在声明的时候省略掉了结构体标签(tag)。

那么在上面代码的基础上,下面的代码合法吗?

p = &x;

警告:

编译器会把上面的两个声明当成完全不同的两个类型,所以是非法的。

匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使用一次。

2.结构体的自引用

在结构中包含一个类型为该结构本身的成员是否可以呢?

如,定义一个链表的节点:

struct Node 
{int data;struct Node next;
};

上面的代码正确吗?如果正确,那sizeof(struct Node)是多少?

仔细分析,其实是不行的,因为一个结构体中再包含一个同类型的结构体变量,这样结构体变量的大小就会无穷的大,是不合理的。

正确的自引用方式:

struct Node 
{int data;//数据域struct Node* next;//指针域
};

在结构体自引用使用的过程中,夹杂了typedef对匿名结构体类型重命名,也很容易引入问题,如:

typedef struct 
{int data;struct Node* next;
}Node;

因为Node是对前面的匿名结构体类型的重命名产生的,但是在匿名结构体内部提前使用Node类型来创建成员变量,这是不行的。

解决方案如下:

typedef struct Node
{int data;struct Node* next;
}Node;

定义结构体尽量不要使用匿名结构体了。

3.结构体内存对齐

我们已经掌握了结构体的基本使用了。

现在我们深入讨论一个问题:计算结构体的大小。

这也是一个特别热门的考点:结构体内存对齐

3.1对齐规则

首先得掌握结构体的对齐规则:

1. 结构体的第⼀个成员对齐到和结构体变量起始位置偏移量为0的地址处
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的⼀个对齐数与该成员变量大小的较小值。
- VS 中默认的值为 8
- Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小
3. 结构体总大小为最大对齐数(结构体中每个成员变量都有⼀个对齐数,所有对齐数中最大的)的
整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构
体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。
//练习1
struct S1
{char c1;int i;char c2;
};

由上图可知,到c2总共占用了9个字节,再根据第4条规则可知,最大对齐数为4,所以该结构体的大小是12个字节。 

//练习2
struct S2
{char c1;char c2;int i;
};

 

由上图可知,到i总共占用了8个字节,再根据规则4,最大对齐数为4,所以该结构体的大小为8个字节。

//练习3
struct S3
{double d;char c;int i;
};

 

由图可知,到i总共占用16个字节,再根据规则4,最大对齐数为8,所以该结构体的大小为16个字节。

//练习4-结构体嵌套问题
struct S4
{char c1;struct S3 s3;double d;
};

 

由图可知到d总共占用了32个字节,再根据规则4,最大对齐数为8,所以改结构体的大小为32个字节。

3.2为什么存在内存对齐?

平台原因(移植原因):

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对齐成8的倍数,那么就可以用⼀个内存操作来读或者写值了。否则,我们可能需要执行两次内存访问,因为对象可能被分放在两个8字节内存块中。

 总的来说:结构体的内存对齐是拿空间来换取时间的做法。

所以在设计结构体的时候,我们既要满足对齐,又要节省空间,要让占用空间小的成员尽量集中在一起。

例如:

struct S1
{char c1;int i;char c2;
};
//变成
struct S2
{char c1;char c2;int i;
};

3.3修改默认对齐数

#pragma这个预处理指令,可以改变编译器的默认对齐数。

#include <stdio.h>
#pragma pack(1)//设置默认对齐数为1
struct S
{char c1;int i;char c2;
};
#pragma pack()//取消设置的对齐数,还原为默认
int main()
{printf("%d\n", sizeof(struct S));return 0;
}

结构体在对齐方式不合适的时候,我们可以自己更改默认对齐数。

4.结构体传参

struct S
{int data[1000];int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{printf("%d\n", ps->num);
}
int main()
{print1(s);//传结构体print2(&s);//传地址return 0;
}

上面的print1print2函数哪个更好?

答案是:print2

原因:

结论:结构体传参的时候,要传结构体的地址。
http://www.dtcms.com/wzjs/87059.html

相关文章:

  • 海洋专业做网站网站怎样优化文章关键词
  • wordpress 分类目录 标题深圳优化seo排名
  • 做java网站后台开发需要什么技能昆明网络推广方式有哪些
  • 宁波网站建设地址搜索seo优化托管
  • 个人可以做购物网站吗广告联盟app下载
  • 涉县网站设计免费网络营销平台
  • 泉州专业建站公司爱站数据
  • 六安手机网站建设地推团队
  • 网站服务合同用交印花税吗浙江seo
  • 南京建设网站报价网络营销工作内容是什么
  • 网站开发公司小程序开发b站是哪个网站
  • 建设网站联盟网易疫情实时最新数据
  • 网站开发域名注册中国十大热门网站排名
  • 网站制作公司官网首页域名流量查询工具
  • 丝袜用什么做的视频网站91手机用哪个浏览器
  • 国务院网站官网建设部青岛官网seo公司
  • 吉林住房和城乡建设部网站广告网站有哪些
  • 重庆 企业网站建设百度搜索热词查询
  • 记事本里做网站 怎么把字体三一crm手机客户端下载
  • 襄樊网站建设襄樊免费网站大全下载
  • 美食美客网站建设谷歌浏览器网页版在线
  • 招聘网站建设需求优化网站推广排名
  • 中企动力做网站多少钱松松软文平台
  • dede手机网站制作搜索引擎优化心得体会
  • 网站首页加载特效网络工程师培训一般多少钱
  • 石家庄网站建设推广电话网络营销成功案例有哪些2022
  • wordpress打不开了seo网站推广方案策划书
  • 河南郑州网站建设哪家公司好最新的新闻 最新消息
  • 1688购物平台河北seo网络优化培训
  • wordpress加密视频播放器外贸网站建设优化推广