威尼斯人网址C++之结构体struct,布局体struct

本条数据构造是这般的: 
   struct hostent { 
   char *h_name; 
   char **h_aliases; 
   int h_addrtype; 
   int h_length; 
   char **h_addr_list; 
   }; 
   #define h_addr h_addr_list[0]  
那边是那几个数据构造的详细资料:  
struct hostent:  
  h_name – 地址的规范名称。 
  h_aliases – 空字节-地址的思忖名称的指针。 
  h_addrtype –地址类型; 平日是AF_INET。  
  h_length – 地址的比特长度。 
  h_addr_list – 零字节-主机互联网地址指针。互连网字节顺序。 
  h_addr – h_addr_list中的第生机勃勃地址。 
gethostbyname(卡塔尔(قطر‎ 成功时再次回到叁个针对构造体 hostent 的指针,大概 是个空 (NULL卡塔尔国 指针。(可是和早先不一样,不设置errno,h_errno 设置错 误新闻。请看下边包车型客车 herror(卡塔尔国。卡塔尔(قطر‎可是哪些接收呢? 这些函数可不象它看上去那么难用。 
此间是个例子: 
#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
int main(int argc, char *argv[]) 

   struct hostent *h; 
   if (argc != 2) { /* 检查命令行 */ 
      fprintf(stderr,”usage: getip address\n”); 
      exit(1); 
   } 
   if ((h=gethostbyname(argv[1])) == NULL) { /* 获得地点音讯 */ 
      herror(“gethostbyname”); 
      exit(1); 
   } 
   printf(“Host name : %s\n”, h->h_name); 
   printf(“IP Address : %s\n”,inet_ntoa(*((struct in_addr *)h->h_addr))); 
   return 0; 

在行使 gethostbyname(卡塔尔 的时候,你不可能用perror(卡塔尔国 打字与印刷错误音讯 (因为 errno 未有动用卡塔尔国,你应有调用 herror(卡塔尔国。
一定轻松,你只是传递一个封存机器名的字符串(比方 “whitehouse.gov”State of Qatar 给gethostbyname(卡塔尔国,然后从重临的数据布局 struct hostent 中获取新闻。
唯风姿罗曼蒂克或然令人不解的是出口 IP 地址音讯。h->h_addr 是一个 char *, 但是 inet_ntoa(State of Qatar 需求的是 struct in_addr。因此,我转换 h->h_addr 成 struct in_addr *,然后拿走数码。 

C++之构造体struct,布局体struct

1.简介

#
C++提供部分骨干的数据类型(int,float,double,char等),但由于程序管理的标题普通较复杂,基本的数据类型不能知足程序需求,由此C++允许顾客依据供给自定义数据类型。C/C++的布局体是带有肖似/区别数据类型数据项的组合项,关键字struct标志布局体。

2.结构体类型的注脚

# 纵然在文件起首证明构造体类型,则具备的函数利用该协会体类型定义变量。

#
假如在函数中声称布局体类型,则独有本函数能够动用该组织体类型定义变量。

  1 struct 结构体类型名
  2 {
  3  成员名;
  4 };

内部存款和储蓄器对齐的三大口径:

Go 中的struct与C中的struct极度相通,况兼Go未有class
接纳 type <Name> struct{} 定义构造,名称遵守可以见到性准则

构造体是生机勃勃种会集,它个中包涵了五个变量或数组,它们的品类能够长期以来,也能够不相同,每一种那样的变量或数组都称呼结构体的分子(Member)


1>假使构造体里面包车型客车分子变量都是主导数据类型(int,char,float,double,指针),第叁个分子变量从内存偏移量为0开头分配;前面包车型客车分子变量从内部存款和储蓄器偏移量是它自身的字节数的翻番开始分配;

type person struct{
Name string
Age int
}

像 int、float、char
等是由C语言自己提供的数据类型,不可能再进行分拆,大家称为基本数据类型;而构造体能够分包几个主导项目标数量,也足以满含其余的构造体,大家将它叫做复杂数据类型或协会数据类型。

动用那几个东西,首先要含有2个头文件:
#include <netdb.h>
#include <sys/socket.h>

3.组织体类型变量的定义和起始化

#先表明布局体类型后定义构造体变量

  1 struct Student
  2 {
  3  int age;
  4  char sex;
  5 };
  6 Student std;  

1.简介 #
C++提供部分主导的数据类型(int,float,double,char等),但出于程序处理的难题平常较复杂,基本的数据…

2>假设成员变量中富含布局体成员变量或然数组,举个例子说struct Student{
char sex;int
age;};从内存偏移量为成员变量字节数最大的字节数(int)的翻番起首分配

func main(){
a := person{}
a.Name = “joe”
a.Age = 19
fmt.Println(a)

布局体的定义

/**
 *  定义一个结构体, 结构体本质上也是一种数据类型
 *  类型是Books的结构体
 */
struct Books
{
    char  title[50];
    char *subject;
    int   book_id;
};
//char[] 和 char * 都可以声明一个字符, 但是是有区别的, char[] 可以直接操作字符串中的每个字符, 而char * 则不可以. 
char[]是数组, 不是指针, 指针赋值可以使用点的方式或者->, 数组赋值字符串只能使用strcpy()的方式, char * 则可以直接使用(.)操作符和赋值

struct hostent *gethostbyname(const char *name);
以此函数的流传值是域名依然主机名,例如 www.google.com,wpc 等等。
传出值,是二个hostent的构造(如下)。假诺函数调用退步,将重返NULL。

3>最终竣事的时候,全体的字节数若是最大字节数成员变量的翻番

b := pserson{
Name : “jole”,
Age : 12,
}
fmt.Println(b)
}

构造体变量

    struct Books Book1;        /* 声明 Book1,类型为 Book */
    //单个赋值
//    Book1.title = "C Programming";     /*title是数组, 不是指针, 指针赋值可以使用点的方式或者->, 数组赋值字符串只能使用strcpy()的方式*/
    strcpy( Book1.title, "C Programming");
    Book1.subject = "iOS 10";   /* 这个是指针, 可以直接赋值 */

    //指定初始化,成员顺序可以不定
    struct Books book = {
        .title = "ios开发",
        .subject= "计算机",
        .book_id = 100
    };

//按照成员声明的顺序初始化
    struct Books book1 = {"iOS", "计算机", 100};

您也得以在概念构造体的同期定义布局体变量:

/**
 *  这种写法是在定义时声明了变量为subject, 使用时不需要struct Subject subject 这种写法
 *  而是直接使用subject就可以了
 */
struct Subject
{
    char *sub;
    int   book_id;
}subject; 

使用

subject.sub = "计算机"; //不需要使用struct关键字声明

别的界分概念构造体的方法

1. 在定义结构体的同时定义多个结构体变量:
struct Subject
{
    char *sub;
    int   book_id;
}subject1, subject2; 
2. 在定义结构体的同时定义结构体变量并赋值
struct Subject
{
    char *sub;
    int   book_id;
}subject = {"计算机", 100};
3.如果需要变量是固定的,后面不需要再使用结构体名定义其他变量,那么在定义时也可以不给出结构体名,如下所示:
struct
{
    char *sub;
    int   book_id;
}subject = {"计算机", 100};

布局体设置外号

/**
 *  这种写法是给
 *  struct person {
        char *name;
    }
 *  设置一个别名Person
 */
typedef struct person {
    char *name;
} Person;

在行使时 Person <==> struct person , 二者是等价的

急需留意的是,布局体是风流倜傥种自定义的数据类型,是创办变量的模版,不占用内部存款和储蓄器空间;布局体变量才含有了可信赖的数额,要求内部存款和储蓄器空间来积累。


struct hostent {
  char  *h_name;
  char  **h_aliases;
  int   h_addrtype;
  int   h_length;
  char  **h_addr_list;
  };
解释一下这些布局:
其中,
  char *h_name
表示的是主机的规范名。比方 www.google.com  的标准名其实是www.l.google.com  。
  char   **h_aliases
代表的是主机的小名。 www.google.com  正是google他协和的小名。有时,有的主机也许有某个个外号,那么些,其实皆感到着轻松顾客记念而为本人的网址多取的名字。
  int   h_addrtype
表示的是主机ip地址的体系,到底是ipv4(AF_INET),还是ipv6(AF_INET6)
  int   h_length 代表的是主机ip地址的尺寸
  int   **h_addr_lisst
表示的是主机的ip地址,注意,那一个是以网络字节序存款和储蓄的。千万不要一贯用printf带%s参数来打那个事物,会有标题标喀。所以到真正需求打字与印刷出这么些IP的话,须要调用inet_ntop()。

*/

支撑针对本身的指针类型成员
支持无名氏布局,可用作成员或概念成员变量
无名布局也能够用来map的值
能够行使字面值对布局进行先导化
允许直接通过指针来读写布局成员
同样等级次序的成员可进行直接拷贝赋值
支持 == 与 !=比较运算符,但不援助 > 或 <
扶植佚名字段,本质上是概念了以有个别项目名叫名称的字段
内置构造作为无名字段看起来像世襲,但不是后续
能够应用无名字段指针

构造体数组

所谓结构体数组,是指数组中的每一种成分都以多少个布局体。在实际上选择中,布局体数组常被用来代表叁个怀有黄金时代致数据布局的部落,比如四个班的学习者、叁个车间的工作者等。

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组 
    float score;  //成绩
}class[5];

布局体数组在概念的还要也能够最初化,比方:

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组 
    float score;  //成绩
}class[5] = {
    {"Li ping", 5, 18, 'C', 145.0},
    {"Zhang ping", 4, 19, 'A', 130.5},
    {"He fang", 1, 18, 'A', 148.5},
    {"Cheng ling", 2, 17, 'F', 139.0},
    {"Wang ming", 3, 17, 'B', 144.5}
};

操作

取值
class[4].score;
修改 Li ping 的学习小组;
class[0].group = 'B';

const char *inet_ntop(int af, const void *src, char *dst, socklen_t
cnt) :
本条函数,是将品种为af的互联网地址构造src,转换来主机序的字符串格局,寄存在长度为cnt的字符串中。
那些函数,其实正是回来指向dst的贰个指南针。假设函数调用错误,重返值是NULL。

void test1()

func main(){
a := pserson{
Name : “jole”,
Age : 12,
}
fmt.Println(a)

布局体和指针

指南针也得以本着贰个布局体,定义的方式平时为:
struct 布局体名 *变量名;

    //声明结构体变量
    struct Books book = {"iOS", "计算机", 100};
    /* 结构体指针 */
    struct Books *strP = &book;
    /* 获取结构体成员 */
    printf("%s", strP->title);
    printf("%s", (*strP).title);

潜心,构造体变量名和数组名不一致,数组名在表达式中会被转移为数组指针,而布局体变量名不会,无论在其余表明式中它表示的都以全方位群集本人,要想获得布局体变量的地点,必得在前边加&,所以给
pstu 赋值只好写作:

struct stu *pstu = &stu1;

而不可能创作:

struct stu *pstu = stu1;

还应该小心,构造体和结构体变量是七个例外的概念:构造体是黄金年代种数据类型,是意气风发种创制变量的模板,编写翻译器不会为它分配内部存款和储蓄器空间,有如int、float、char
那几个重大字自个儿不占用内部存款和储蓄器同样;结构体变量才含有实实在在的数目,才须求内部存款和储蓄器来存储。上边包车型客车写法是漏洞非常多的,一点都不大概去取叁个构造体名的地点,也不可能将它赋值给别的变量:

struct stu *pstu = &stu;
struct stu *pstu = stu;

收获结构体成员

因此构造体指针能够博得布局体成员,常常情势为:

(*pointer).memberName

或者:

pointer->memberName

先是种写法中,.的前期级高于,(pointer卡塔尔国两侧的括号不能够少。假若去掉括号写作pointer.memberName,那么就等效于(pointer.numberName卡塔尔(قطر‎,那样意义就完全不对了。

第三种写法中,->是三个新的运算符,习贯称它为“箭头”,有了它,能够透过布局体指针直接拿走布局体成员;那也是->在C语言中的唯意气风发用处。

 

{

A(a卡塔尔(قطر‎ //这里传入不是地方 里面输出的age变13
fmt.Println(a卡塔尔 //这里输出的age依旧12

上面是例程,有详尽的讲解。

//struct Student是大家和好定义的叁个新的数据类型

A(&aState of Qatar //这里传入是地方 里面输出的age变13
fmt.Println(a卡塔尔(قطر‎ //这里输出的age也是13

#include <netdb.h>
#include <sys/socket.h>

struct Student

//为了特别有协理这就足以
b := &pserson{
Name : “jole”,
Age : 12,
}

int main(int argc, char **argv)
{
 char *ptr,**pptr;
 struct hostent *hptr;
 char str[32];
 /* 得到命令后先是个参数,即要深入分析的域名或主机名 */
 ptr = argv[1];
 /* 调用gethostbyname(卡塔尔国。调用结果都留存hptr中 */
 if( (hptr = gethostbyname(ptr) ) == NULL )
 {
  printf(“gethostbyname error for host:%s\n”, ptr);
  return 0; /* 假若调用gethostbyname发生错误,重临1 */
 }
 /* 将主机的标准名打出来 */
 printf(“official hostname:%s\n”,hptr->h_name);
 /* 主机也有八个别称,将有所别称分别打出来 */
 for(pptr = hptr->h_aliases; *pptr != NULL; pptr++)
  printf(”  alias:%s\n”,*pptr);
 /* 总部址类型,将地址打出去 */
 switch(hptr->h_addrtype)
 {
  case AF_INET:
  case AF_INET6:
   pptr=hptr->h_addr_list;
   /* 将刚刚得到的装有地方都打出来。当中调用了inet_ntop()函数 */
   for(;*pptr!=NULL;pptr++)
    printf(”  address:%s\n”, inet_ntop(hptr->h_addrtype, *pptr,
str, sizeof(str)));
   break;
  default:
   printf(“unknown address type\n”);
   break;
 }
 return 0;
}

{

fmt.Println(b)

char name[20];

A(b卡塔尔(قطر‎ //这里就足以一直传入地址
fmt.Println(b)

int age;

//无名布局
c := &struct {
Name string
Age int
}{
Name : “joe”
Age : 19
}

float score;

}
func A(per *person){
per.Age =13
fmt.Println(“A”,per)
}

};

func B(per *preson){
}
—end

//数据类型+变量名;

//嵌套无名布局
type person struct {
Name string
Age int
Contact struct {
Phone string
City string
CN,Sex string//三个概念类型
}
}

struct Student stu1={“sq”,10,100.0};

func main(){
a := person{Name: “joe”, Age: 19}
a.Contact.Phone = “12456” //只可以通过如此的措施开展构造体中的结构体
a.Contact.City= “wenzhou”
fmt.Println(a)
}
–end

struct Student stu2; 

type person struct{//那样归于佚名布局
string
int
}

//    语法:相当于‘的’

func main(){
a := person{ “joe”, 18}
fmt.Println(a)
}
—end

stu2.age=10;

//嵌入构造 相似预面向指标的世袭
type human struct {
Sex int
}

stu2.score=99.0;

type teacher struct {
human
Name string
Age int
}

strcpy(stu2.name, “rose”);

type student struct {
human
Name string
Age int
}

printf(“name=%s\nage=%d\nscore=%f\n”,stu1.name,stu1.age,stu1.score);

func main() {
a := teacher{Name: “jjj”, Age: 19, human: human{Sex: 0}}
b := teacher{Name: “jjj”, Age: 20, human: human{Sex: 1}}
a.Age = “j23”
a.human.Sex = 100
a.Sex = 200 //嵌入式的性状
}

威尼斯人网址 1

/*

数组是叁个集合类:肖似档期的顺序的变量

布局体也是五个会集类:能够一直以来,能够不一致品种的变量

*/

}

void test2()

{

struct Student

{

char sex;//0

float score;//4–7

double kill;//8—15

long age;//16–19

};

long size=sizeof(struct Student);

printf(“size=%ld\n”,size);

威尼斯人网址 2

}

void test3()

{

struct Birthday

{

int year;//0—3

int month;//4—7

int day;//8—11

};

struct Student

{        int age;//0—3

char name[20];//4—-23

struct Birthday birth;//24—-35

};

//1.

struct Student stu={10,”sq”,{1990,1,1}};

//2.

struct Student stu2;

stu2.age=20;

strcpy(stu2.name,”rose”);

stu2.birth.year=2000;

stu2.birth.month=1;

stu2.birth.day=1;

printf(“%ld\n”,sizeof(struct Student));

}

威尼斯人网址 3

void test4()

{

//1.

struct Student    {

char sex;

int age;

}stu2[3]={{‘x’,10},{‘s’,10},{‘c’,10}};

//2.无名氏布局体

struct

{

int age;

char name[20];

}stu;

struct

{

int age;

char name[20];

}stu1;

}

void test5()

{

//是将现成的数据类型重命名成你想要的数据类型

typedef int size;

struct Student

{

char sex;

int age;

};

typedef struct Student Student;

typedef struct Person

{

char sex;

int age;

}Person;

struct Person p={‘x’,10};

Person p1={‘m’,20};

}

威尼斯人网址 4

void test6()

{

typedef struct Student

{

char sex;

int age;

}Student;

Student stu={‘x’,10};

Student *p=&stu;

(*p).sex=’m’;

(*p).age=20;    printf(“sex=%c\nage=%d\n”,stu.sex,stu.age);

p->sex=’n’;

p->age=30;

printf(“sex=%c\nage=%d\n”,stu.sex,stu.age);

}

威尼斯人网址 5

/*
将stu[4]={{‘x’,30},{‘x’,11},{‘x’,40},{‘x’,13}};写一个函数达成年龄从小到大排序,排序完写叁个函数打字与印刷音讯

*/

typedef struct Student

{

char sex;

int age;

}Student,* pStudent;

/*

威尼斯人网址 6

typedef struct Student Student;

typedef struct Student * pStudent;

*/

void printInfo(Student stu[],int size)

{

int i=0;

for (; istu[j].age)

{

Student temp=stu[i];

stu[i]=stu[j];

stu[j]=temp;

}

}

}

}int main()

{

Student stu[4]={{‘v’,40},{‘x’,11},{‘f’,50},{‘m’,13}};

//    int arr[10]={12,3};

//    int size1=sizeof(arr)/sizeof(int);

int size=sizeof(stu)/sizeof(Student);

printf(“排序以前:\n”);

printInfo(stu,4);

blueSort(stu,4);

`printf(“排序之后:\n”);    printInfo(stu,4);

return 0;

}

威尼斯人网址 7

发表评论

电子邮件地址不会被公开。 必填项已用*标注