结构体大小计算、typedef、函数指针小记

结构体大小计算

计算结构体大小的规则:

  1. 每一个成员的偏移量都必须是该成员的倍数。
  2. 结构体的大小必须是该结构体字节数最大成员的倍数。

先来说说什么是偏移量,某个成员的实际地址和结构体首地址之间的距离

struct data {
	int a;
	char b;
	int c;
}
  • 因为 a 为首地址,因此偏移量为 0
  • 同时 int a 在内存中占 4 个字节,也就是是 b 的偏移量;由于 4 是 1 的整数倍,因此不用填充
  • c 的偏移量为 4 + 1 = 5, 5 不是 4 的整数倍,需要加 3,于是 b 后面加了 3 个字节
  • 最后来看看第二条规则,整个结构体中,int 占用内存最多,整个结构体大小为 4 + 1 + 3(填充字节) + 4 = 12 个字节,为 4 的倍数,因此结构体的大小为 12

之所以讲这个,是因为这关系到内存对齐,程序必须是加载到内存才能执行,而 CPU 访问内存时加载数据不是一个字节一个字节的加载,那样的话效率太低,而是一块一块加载的,一块长度可以是 2、4、8、16 字节大小,因此内存对齐了,那么 CPU 只需一次性便可加载,以空间换时间,从而提高效率。

typdef

typedef 就是给类型取别名,别名一般出现在变量名的位置。

int number;
typedef int number;

下面的这个 number 就是 int 的别名,今后可以使用 number 来声明变量

number num;

而且如果今后 number 需要由 int 型改成 long 型也很简单,只需调整下声明方式

typedef long number;

说到这里,大伙应该也会想起 define 这个关键字,这个主要要用来声明宏的,当然了也可以做些简单类型声明

#define int number;

number num;

在预处理阶段,会把 number 替换成 int,再来看看下面的这个

#define int* ptr;
ptr a1,a2;

替换后变成

int* a1,a2;

a1 声明为 int 型指针,而 a2 却不是,显然没有达到整体声明的效果。

再回到一开始声明的结构体

struct data dt;

是不是每次都得写 struct data,那么使用 typedef 可以简化

typedef struct data {
	int a;
	char b;
	int c;
} data;
data dt;

函数指针

C 语言中万物皆有内存地址,函数也不例外。先从简单的 int 型指针说起

int *a;

声明了一个 int 型的指针 a,a 存放的是 int 型的指针地址,在 64 位的系统中内存大小为 8 位。

#include <stdio.h>
int add(int, int);

int main(int argc,char *argv[])
{
	int a=1;
	int b=2;
	printf("a+b=%d\n", add(a, b));
}

int add(int a, int b)
{
	return a+b;
}

上述的 add 方法,在内存中也有地址,可以使用 typedef 来声明函数指针

typedef (*func)(int, int);

func 代表内存 add 的起始地址。

#include <stdio.h>
int add(int, int);
typedef (*func)(int, int);

int main(int argc,char *argv[])
{
    int a=1;
    int b=2;
    func f1 = add;
    func f2 = add;
    printf("a+b=%d\n", f1(a, b));
    printf("a+b=%d\n", (*f2)(a, b)); // ANSI C认为 f1 和 (*f2) 这两种形式等价
}

int add(int a, int b)
{
    return a+b;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,结构体指针typedef是两个不同的概念。结构体指针是指向结构体类型的指针变量,而typedef是用来给数据类型取别名的关键字。 结构体指针可以用来访问和操作结构体类型的成员。通过结构体指针,我们可以方便地对结构体类型的数据进行修改和传递。 而typedef关键字则可以用来为数据类型定义一个新的名称,以方便在程序中使用。通过typedef,我们可以为结构体类型定义一个别名,使得我们可以直接使用该别名来声明结构体类型的变量,而不需要每次都写出完整的结构体类型名。 举个例子来说明,假设我们有以下结构体定义: ``` typedef struct { int x; int y; } Point; ``` 通过上面的定义,我们为结构体类型"struct { int x; int y; }"取了一个别名"Point"。这样,我们就可以使用"Point"来声明结构体类型的变量了: ``` Point p1; ``` 另外,结合结构体指针typedef的使用,我们可以定义一个结构体指针类型的别名。比如: ``` typedef struct Node { int data; struct Node *next; } Node, *NodePtr; ``` 上面的代码中,我们为结构体类型"struct Node"取了一个别名"Node",并且定义了一个结构体指针类型的别名"NodePtr",它等价于"struct Node *"。这样,我们就可以使用"NodePtr"来声明结构体指针类型的变量了: ``` NodePtr p2; ``` 综上所述,结构体指针typedef在C语言中是两个不同的概念,但它们可以结合使用,使得我们更方便地操作结构体类型的数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值