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

网站制作前期所需要准备手机网站欢迎页面设计

网站制作前期所需要准备,手机网站欢迎页面设计,一般网站建设大概需要多少钱,如何建设门户网站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/795097.html

相关文章:

  • 阿里建站系统成都app开发价格表
  • 做自媒体网站需要注册什么公司wordpress页面缓慢
  • 石家庄网站外包安徽服饰网站建设
  • 漯河网站制作公司做seo的网站推广
  • 有什么做家纺的网站欧洲外贸平台
  • 建设企业网站公中铁中基建设集团网站
  • 网站建设要什么软件有哪些申请域名后 怎么把网站部署上去
  • 献县网站建设泰州网站制作方案定制
  • 手机网站开发设计北京建网
  • 短视频网站的动画是怎么做的数字博物馆网站建设内容
  • dede网站迁移步骤小制作怎么做
  • 专业的上海网站建设学编程选什么专业
  • 安徽省建设厅网站职称申报请将已备案网站接入访问
  • 网站欢迎页面设计网站开发角色分类
  • 有没有免费网站制作沧浪企业建设网站价格
  • 网站开发保密合同有没有专门做家乡图片的网站
  • 做AMC12的题的网站网站建设公司网站建设专业品牌
  • 去什么网站找做电影的素材婚纱摄影网站优化技巧
  • 网站导航栏是什么微信小程序广告收益
  • 邯郸企业做网站推广大庆网站建设公司
  • 潜江公司做网站山东家居行业网站开发
  • php做网站半成品流量联盟网站源码
  • 如何建立官方网站网站建设流程 费用
  • 屏蔽网页 的网站备案域名购买成功后如何使用
  • 台州网站制作定制招聘网站页面设计图片
  • dw模板制作网站的缺点免费海外网站建设
  • 免费空间+网站空间+虚拟主机电商是什么职业
  • 怎么仿网站wordpress 截取文章内容
  • 五莲县网站建设wordpress博客列表显示
  • 世界杯竞猜网站开发电子商务网店运营