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

商务网站建设试卷外贸推广有哪些好的方式

商务网站建设试卷,外贸推广有哪些好的方式,电脑做服务器发布网站吗,南京网站建设推广C语言中自定义类型 结构体结构体变量的创建和初始化结构体传参结构体内存对齐(如何存储) 联合体(共用体)联合体创建和初始化联合体大小(如何存储) 枚举类型枚举类型创建枚举类型初始化枚举的优点(相较于define) 前言 C语言中有内置类型和自定义类型,内置类型就像int…

C语言中自定义类型

  • 结构体
    • 结构体变量的创建和初始化
    • 结构体传参
    • 结构体内存对齐(如何存储)
  • 联合体(共用体)
    • 联合体创建和初始化
    • 联合体大小(如何存储)
  • 枚举类型
    • 枚举类型创建
    • 枚举类型初始化
    • 枚举的优点(相较于define)

前言
C语言中有内置类型和自定义类型,内置类型就像int 、double等等,其自带的一些类型,但有时候这些类型满足不了一些特定的要求,所以C语言也提供了一些自定义类型:结构体、联合、枚举


结构体

struct tag
{//结构体成员变量member-list;
}variable-list;//结构体变量名称
//可以在使用时候创建,也可以在创建结构体时创建

例如:创建一个学生的结构体

struct Stu {char name[20];int age;char sex[5];
}; //这里的分号不可以省略

这上面就相当于一个结构体的声明,创建了一个结构体类型,那如何使用呢?

结构体变量的创建和初始化

可以创建的同时初始化

struct Stu {char name[20];int age;char sex[5];
};int main() 
{
//创建结构体类型变量并初始化struct Stu s = { "张三",18,"male" };struct Stu s1 = {"lisi",18,"male"};
}
#include<stdio.h>
struct Stu {char name[20];int age;char sex[5];
};int main() 
{
//创建一个结构体变量并初始化struct Stu s = { "张三",18,"male" };printf("%s\n", s.name);printf("%d\n", s.age);printf("%s\n", s.sex);//可以使用指针来指向这个结构体,来进行访问struct Stu* p = &s;printf("%d\n", (*p).age);printf("%s\n", p->name);return 0;
}
这里使用变量名.结构体成员来访问
如果是一个指针指向一个结构体的话,有两种访问形式
变量名->成员变量
(*变量名).结构体成员

运行结果如下
在这里插入图片描述

结构体传参

结构体传参分为传值调用和传址调用

#include<stdio.h>
struct Stu {int age;char name[20];
};
//传值
void print1(struct Stu p)
{printf("%d\n", p.age);
}
//传址
void print2(struct Stu* p)
{printf("%d\n", (*p).age);
}
int main()
{struct Stu s = { 18,"sansan" };print1(s);print2(&s);return 0;
}

运行结果如下
在这里插入图片描述
传址调用可以修改结构体变量的值,但是传值调用则不可以

#include<stdio.h>
struct Stu {int age;char name[20];
};
//传值
void print1(struct Stu p)
{p.age = 19;
}
//传址
void print2(struct Stu* p)
{(*p).age = 20;
}
int main()
{struct Stu s = { 18,"sansan" };print1(s);printf("调用传值调用后age:%d\n", s.age);print2(&s);printf("调用传址调用后age:%d\n", s.age);return 0;
}

这里我们通过传值调用和传地址调用,发现这里的传地址调用可以修改结构体的变量的值,但是传值调用则不可以
在这里插入图片描述
结构体在进行传参的时候,传递地址比较好,因为如果传值调用的话,形参是实参的一份临时拷贝,如果这个结构体变量非常大,这可能在是将和空间上的开销比较大,所以传地址调用更好一点

结构体内存对齐(如何存储)

上面我们已经对结构体有所了解了,但是这有个新问题,结构体存储的时候是占多少字节呢?这就引出了:结构体内存对齐

对齐规则

1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
2.剩下的成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
这里的对⻬数=编译器默认的⼀个对⻬数与该成员变量⼤⼩整数倍的较⼩值
-VS 编译器中默认的值为 8
-Linux系统中gcc没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩
3.结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。
4.如果嵌套了其他结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,这个结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍
也就是要考虑结构体变量以及嵌套结构体变量其中的最大对齐数

我们就以下面这两个结构体来举例

#include<stdio.h>
struct S1
{char c1;int i;char c2;
};
struct S2
{char c1;char c2;int i;
};
int main()
{//计算S1与S2分别的字节大小printf("%zd\n", sizeof(struct S1));printf("%zd\n", sizeof(struct S2));return 0;
}

运行结果如下
在这里插入图片描述

从运行结果我们发现一个问题这里的结构体变量的大小,并不是简单的成员变量所占字节数相加,而是经过内存对齐得出的结果
S1 和 S2结构体带下分析如下

在这里插入图片描述


在这里插入图片描述
这里的两个结构体S1大小为12,S2大小8

嵌套类型的结构体总大小计算

#include<stdio.h>
struct S3
{double d;char c;int i;
};//结构体嵌套问题 
struct S4
{char c1;struct S3 s3;double d;
};
int main()
{printf("%zd\n", sizeof(struct S3));printf("%zd\n", sizeof(struct S4));return 0;
}

在这里插入图片描述


在这里插入图片描述
这里我们在VS2022这个编译器下,分析的结果是结构体S3的总大小是16,S4的总大小是32

运行结果如下
和我们推测一样
在这里插入图片描述
为什么要有这种对齐规则呢

1.平台原因(硬件原因)
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,
否则出现硬件异常
2.性能原因
数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬,原因是这种访问需要访问两次,假设一个编译器只能8个地
地址进行存储,这样我们每次保证存储是8的倍数,这样就方便访问,提高效率
3.我们可以发现上面结构体就是按照对齐规则存储,这是为了快捷访问,相当于牺牲了一部分空间来换取时间

但是我们可以减少浪费
在这里插入图片描述
就像上面的两个结构体S1和S2,虽然成员变量的一样,但位置不同结果也不同,我们可以让占用小的空间尽量集中一起,这样可以节省空间

我们这里的VS2022有自己对齐规则,我们可以修改其 默认的对齐数,来改变其大小
#pragma 这个预处理指令,可以改变编译器的默认对⻬数

#include<stdio.h>
#pragma pack(1)//设置默认对⻬数为1 
struct S
{char c1;int i;char c2;
};int main()
{//输出的结果是什么? printf("%zd\n", sizeof(struct S));return 0;
}

在这里插入图片描述
我们如果按照VS编译器的话,这里的大小是12,但是我们这里设置默认对齐数为1,也就是每个变量是紧挨着存储,所以这里大小是其相加也就是6

联合体(共用体)

联合体创建和初始化

联合体和结构体类似,都是由多个成员组成,这些成员可以是不同类型
但是与结构体不同的是,联合体是所有成员共用同一块内存,所以联合体也叫做共用体

union tag
{//成员变量member-list;
}variable-list;

创建了一个共用体类型

#include<stdio.h>
union Un 
{char c1;int i;char c2;
};

共用体创建和初始化
以及共用体是所有成员占用一块内存吗?我们以下面这个代码来举例

union Un 
{char c1;int i;char c2;
};
int main()
{union Un un = { 0 };printf("%zd\n", sizeof(un));return 0;
}

运行结果如下
在这里插入图片描述
从结果上可以看出,它并不是连续存储,也不像结构体那样根据对齐原则存储,那他是如何存储的呢
上面的联合体的大小是4个字节,因为这里的最大成员变量是int 占4个字节,并且是最大对齐的数4的整数倍

联合体大小(如何存储)

联合体大小计算

联合的⼤⼩⾄少是最⼤成员的⼤⼩。
当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍

那我们来看下面的代码

#include<stdio.h>
union Un1
{char c[5];int i;
};
union Un2
{short c[7];int i;
};
int main()
{//下⾯输出的结果是什么? //最大的是5,但又要是最大对齐数4的整数倍数,所以这里是8printf("%zd\n", sizeof(union Un1));//最大是14,但又要是最大对齐数4的整数倍,所以结果是16printf("%zd\n", sizeof(union Un2));return 0;
}

运行结果如下
在这里插入图片描述

在这里插入图片描述

他们真的是占用同一块内存吗?

#include<stdio.h>
union Un 
{char c1;int i;char c2;
};
int main()
{union Un un = { 0 };//%p是打印地址的,我们看他们是不是真的存储在同一内存printf("%p\n", &(un.c1));printf("%p\n", &(un.i));printf("%p\n", &(un.c2));return 0;
}

运行结果如下
在这里插入图片描述
从这个结果可以看出,共用体它们所占用的是同一个内存
这里如果修改一个成员数值有成员的结果就会改变

#include<stdio.h>
union Un 
{char c1;int i;char c2;
};
int main()
{union Un un = { 0 };//%p是打印地址的,我们看他们是不是真的存储在同一内存un.i = 200;printf("%d\n", un.c1);printf("%d\n", un.c2);printf("%d\n", un.i);return 0;
}

在这里插入图片描述

在这里插入图片描述
char类型的范围是-128 ~ 127,如果超过范围结果是怎样呢
在这里插入图片描述

虽然它们占用同一块内存,但所占的字节数不同,这也导致结果不一样,就像这里的char只会占1个字节8个比特位,而int占4个字节,32比特位,所以这里的char类型打印的和int类型数值不同

枚举类型

枚举顾名思义就是将其成员一一列举
就像生活中一年有12个月,一周有7天一样可以一一列举

枚举类型创建

enum Day//星期
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};
enum Color//三颜⾊
{Red,Green,Blue
};

这里的enum Day 和 enum Color都是枚举类型
{ }下都是可能取值,枚举常量
这些枚举常量都是从0开始,依次增加当然我们也可以给它赋值

枚举类型初始化

默认初始化
我们知道枚举常量都是从0开始,我们那上面的Color枚举来举例

#include<stdio.h>
enum Color//三颜⾊
{Red,//默认存储的是0Green,//1Blue//2
};
int main()
{//创建一个c来接收Redenum Color c = Red;printf("%d\n", c);//0printf("%d\n", Red);//0printf("%d\n", Green);//1printf("%d\n",Blue);//2return 0;
}

运行结果如下
在这里插入图片描述

从结果中可以看出,枚举常量是都是从0开始的,依次增加,并且创建的变量也是存储其常量值

为什么我们这里是说这是枚举常量
在这里插入图片描述

这里我们给枚举常量进行修改,发现是不可以的,因为常量值是不可以修改的,枚举常量是常量

就地初始化
全部初始化

#include<stdio.h>
enum Color//三颜⾊
{Red = 1,Green = 3,Blue = 7
};
int main()
{printf("%d\n", Red);printf("%d\n", Green);printf("%d\n",Blue);return 0;
}

这里我们对Color这个枚举中的枚举常量全部都初始化了,但是不可以在枚举类型外部修改
运行结果如下
在这里插入图片描述
那如果我们只是部分初始化

#include<stdio.h>
enum Color//三颜⾊
{Red = 1,Green,Blue
};
int main()
{printf("%d\n", Red);printf("%d\n", Green);printf("%d\n",Blue);return 0;
}

这里原本第一个是从0开始的,但是我们初始化为1,但是依旧满足依次增加的原则,所以结果为
在这里插入图片描述
那我们只修改中间的呢,依然满足上面依次增加的规则,如果初始化的话,按照初始化的值
就像下面这个,我们只初始化了前面两个枚举常量,那第三个常量值就是第二个常量值+1
在这里插入图片描述

枚举的优点(相较于define)

我们可以使⽤ #define 定义常量,为什么⾮要使⽤枚举?
就像上面的代码,我们用#define来写

#include<stdio.h>
#define Red 1
#define Green 2
#define Blue 3
int main()
{printf("%d\n", Red);printf("%d\n", Green);printf("%d\n", Blue);return 0;
}

运行结果如下,可以生成与枚举类型相同的结果
我们可以发现这里的#define每次只能定义一个,而枚举类型一个可以定义多个对象
在这里插入图片描述

枚举的优点
1.可以增强代码的可读性 ,因为define只是简单的代码替换,无法调试观察
2.和#define使用枚举比较严谨
3.方便使用,可以连续创建多个常量,而#define依次只能定义一个

到这里就结束了,希望大家有所帮助,欲知后事如何,请听下回分解

http://www.dtcms.com/wzjs/71789.html

相关文章:

  • 分类信息多城市网站完整的社群营销方案
  • 做外汇看的国外网站百度广告推广
  • 石家庄市官方网站制作公司网站大概多少钱
  • 网站建设 网页设计 网站制作中国行业数据分析网
  • 网络营销的多种形式和特点seo站内优化技巧
  • 自己做网站需要多少钱百度关键词排名十大排名
  • 南通网站建设排名公司网站安全检测在线
  • 做网站流程内容自己如何制作网页
  • 网站制作应该注意到的问题网站开发
  • 织梦网站模板源码php搜索引擎关键词竞价排名
  • 成都高端网站建设北京seo分析
  • 郴州 网站建设浏览器如何推广自己网站
  • 发卡网站搭建教程b站黄页推广
  • 男做直播网站抖音推广网站
  • 威县做网站哪家便宜长沙做网站推广
  • 如何判断网站做没做404服务营销7p理论
  • 做公益网站怎么赚钱新手如何自己做网站
  • 深圳设计网站公司企业网站注册
  • 建立网站建设百度搜索推广平台
  • 泰兴市城乡建设管理局网站seo计费系统源码
  • 创新型的顺的网站制作小程序排名优化
  • 广州网站建设年底促销公司广告推广方案
  • 网站托管服务适用于百度seo是什么意思呢
  • 无障碍浏览网站怎么做黑帽seo是作弊手法
  • 长春网站建设费用社区推广
  • 万维建设网站互联网广告推广是做什么的
  • 深圳市门户网站建设哪家好qq引流推广软件免费
  • 多语种网站建设想做电商怎么入手
  • 做黄金的网站搜索百度网页版
  • 外贸做网站用什么日本产品和韩国产品哪个好