结构体:结构体的声明、结构体成员的访问、结构体传参etc

结构体

1. 结构体的声明

1.1 结构的基础知识

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

1.2 结构的声明

struct tag
{
   member-list; //成员列表
}variable-list;//变量列表

例如描述一个学生:

typedef struct Stu
{
    char name[20];//名字
    int age;//年龄
    char sex[5];//性别
    char id[20];//学号
}Stu;//全局变量
//分号不能丢

1.3 结构成员的类型

结构的成员可以是标量、数组、指针,甚至是其他结构体。

struct Point
{
    int x;
    int y;
}p1; //声明类型的同时定义变量p1
struct S
{
    char c;
    struct Point p;
    double d;
    char str[20];
};
struct Stu
{
    char name[20];//名字
    int age;//年龄
    char sex[5];//性别
    char hight;//学号
};//全局变量
//分号不能丢
int main()
{
    struct S ss = { 'x',{100,200},3.14,"dog" };
 // struct S ss = { .d = 3.14,.c = 'x',.p.x = 100 };
    printf("%c %d %d %lf %s\n", ss.c, ss.p.x, ss.p.y, ss.d, ss.str);
    struct Point p = { 10,20 };
    struct Stu s = { "LiJun",20,"男",176 };
    printf("x=%d y=%d\n", p.x, p.y);
    printf("%s %d %s %s\n", s.name, s.age, s.sex, s.hight);
    return 0;
}

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

有了结构体类型,那如何定义变量,其实很简单。

struct Point
{
    int x;
    int y; 
}p1; //声明类型的同时定义变量p1

struct Point p2; //全局变量
//定义结构体变量p2

//初始化:定义变量的同时赋初值。
struct Point p3 = {x, y};

struct Stu        //类型声明
{
    char name[15];//名字
    int age;      //年龄
};
struct Stu s = {"LiJun", 20};//初始化

struct Node
{
    int data;
    struct Point p;
    struct Node* next; 
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化

struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

2. 结构体成员的访问

  • 结构体变量访问成员

结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。

例如:

在这里插入图片描述

我们可以看到 s 有成员 name 和 age ;

那我们如何访问s的成员?

struct S s;
strcpy(s.name, "LiJun");//使用.访问name成员
s.age = 20;//使用.访问age成员
  • 结构体指针访问指向变量的成员

    有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针。

访问成员,如下:

struct Stu
{
    char name[20];
    int age;
};
void print(struct Stu* ps)
{
    printf("name = %s   age = %d\n", (*ps).name, (*ps).age);
    //使用结构体指针访问指向对象的成员
    printf("name = %s   age = %d\n", ps->name, ps->age);
}
int main()
{
    struct Stu s = { .age = 20,.name = "LiJun" };
    printf("%s %d\n", s.name, s.age);
    s.age = 30;
    //*char*
    *(s.name) = "LiJun";//err
    strcpy(s.name, "LiJun");
    struct Stu s = { "LiJun", 20 };
    print(&s);//结构体地址传参
    return 0;
}

3. 结构体传参

直接上代码:

//结构体变量.结构体成员名
//结构体指针->结构体成员名
struct S
{
	int data[1000];
	char buf[100];
};
//结构体传参
void print1(struct S ss)
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", ss.data[i]);
	}
	printf("%s\n", ss.buf);
}
//结构体地址传参
void print2(struct S* ps)
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", ps->data[i]);
	}
	printf("%s\n", ps->buf);
}
int main()
{
	struct S s = { {1,2,3},"dog" };
	print1(s);  //传结构体
	print2(&s); //传地址
	return 0;
}

上面的 print1 和 print2 函数哪个好些?

答案是:首选 print2 函数。

原因:

函数传参的时候,参数是需要压栈的。

如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`struct sock` 是 Linux 内核网络协议栈中的一个非常重要的结构,它表示一个通用的套接字(socket)。它的定义在 `<linux/net.h>` 中。 下面是 `struct sock` 的定义: ```c struct sock { /* Socket state: SS_CONNECTED, SS_DISCONNECTING etc */ unsigned short sk_state; /* Protocol family, AF_xxx */ unsigned short sk_family; /* One of SOCK_{STREAM,DGRAM,RAW,..} */ unsigned short sk_type; /* Protocol, usually IPPROTO_TCP, IPPROTO_UDP */ unsigned short sk_protocol; /* Socket table entry */ struct sock *sk_next; struct sock *sk_prev; struct sock *sk_acceptq; /* Wait queue head for reading */ struct wait_queue_head sk_wq; /* Receive queue */ struct sk_buff_head sk_receive_queue; /* Send queue */ struct sk_buff_head sk_write_queue; /* Socket error queue */ struct sk_buff_head sk_error_queue; /* Head of queue of sockets waiting for send space */ struct sk_buff_head sk_backlog; /* Socket buffer space */ unsigned int sk_sndbuf; unsigned int sk_rcvbuf; /* Memory pressure on skbs */ unsigned int sk_wmem_alloc; unsigned int sk_rmem_alloc; /* Socket callback functions */ void (*sk_data_ready)(struct sock *sk, int bytes); void (*sk_write_space)(struct sock *sk); void (*sk_error_report)(struct sock *sk); /* Private socket data, e.g. TCP sock has tx/rx queues */ struct sk_buff_head sk_backlog_tail; void *sk_protinfo; /* Socket creation time */ unsigned long sk_tsq_flags; struct timer_list sk_timer; /* Socket options */ struct sk_options sk_options; /* Misc flags */ unsigned int sk_flags; /* Socket priority */ unsigned short sk_priority; /* Socket multicast options */ struct ip_mreqn sk_omreq; struct ip_mreqn sk_imreq; /* Socket reference count */ atomic_t sk_refcnt; /* Socket user ref count */ atomic_t sk_wmem_refcnt; /* Socket lock */ spinlock_t sk_lock; /* Socket destructor */ void (*sk_destruct)(struct sock *sk); }; ``` 下面是对其中一些字段的解释: - `sk_state`:表示 socket 的状态,例如 `SS_CONNECTED` 表示连接已经建立,`SS_DISCONNECTING` 表示正在断开连接等。 - `sk_family`:表示 socket 的协议族,例如 `AF_INET` 表示 IPv4 协议族,`AF_INET6` 表示 IPv6 协议族等。 - `sk_type`:表示 socket 的类型,例如 `SOCK_STREAM` 表示流式 socket,`SOCK_DGRAM` 表示数据报式 socket 等。 - `sk_protocol`:表示 socket 的协议,例如 `IPPROTO_TCP` 表示使用 TCP 协议,`IPPROTO_UDP` 表示使用 UDP 协议等。 - `sk_next` 和 `sk_prev`:表示一个 socket 链表中的下一个和上一个 socket。 - `sk_acceptq`:表示等待 accept 的 socket 队列。 - `sk_wq`:表示等待读取数据的进程队列。 - `sk_receive_queue`:表示接收到的数据的队列。 - `sk_write_queue`:表示等待发送的数据的队列。 - `sk_error_queue`:表示错误消息的队列。 - `sk_backlog`:表示等待发送的数据的队列。 - `sk_sndbuf` 和 `sk_rcvbuf`:表示发送和接收缓冲区的大小。 - `sk_data_ready`、`sk_write_space` 和 `sk_error_report`:表示 socket 的回调函数。 - `sk_protinfo`:表示私有数据,例如 TCP socket 的 tx/rx 队列。 - `sk_flags`:表示 socket 的标志,例如 `SOCK_NOSPACE` 表示没有足够的空间来发送数据等。 - `sk_priority`:表示 socket 的优先级。 - `sk_refcnt` 和 `sk_wmem_refcnt`:表示 socket 的引用计数。 - `sk_lock`:表示 socket 的锁。 - `sk_destruct`:表示 socket 的析构函数。 总之,`struct sock` 是 Linux 内核网络协议栈中非常重要的一个结构,它包含了 socket 的各种信息和状态,是网络编程中一个重要的概念。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值