不使用sizeof求一个变量的大小

之前在腾讯实习生笔试的时候,遇到一个问题,当时一点思路也没有,现在想了想,找了一些资料,大体上明白了应该如何去做。
问题是:
使用C实现求一个变量的大小,不使用sizeof。

首先我先把我的代码贴上:

#define size(x) ((char*)(&x+1)-(char*)(&x))

该宏定义就实现了刚刚的需求。
首先,我们知道,char是占用一个字节的大小,我们得到一个变量之后,先取其引用,即&x,则该引用指向变量x的首地址。

这里写图片描述

而&x+1,是跨越该x之后的第一个地址。

我们举个例子:
我们有一个数组:

int a[] = {10,20,30,40,50};

我们先看a的内存分布:

这里写图片描述

a也是指向数组第一个元素首地址的,也就是指向元素10所在的位置,则(*a)代表着就是值10,那么(*a+1)就相当于10+1=11;(a+1)指向的是下一个元素的位置,则(*(a+1))代表着就是20。

而&a指向的整个数组的首地址,虽然说整个数组的首地址就是第一个元素的首地址,但是整体感觉来说还是不一样的,这样来看,(*a+1)是数组中的第一个元素值加一,而(&a+1)是整个数组加一,下面这个图很好的诠释了这个问题。

这里写图片描述

所以说,我们想要求得一个变量的大小的话,只要使(&a+1)减去(&a),然后再转化成字节的形式就可以了。

而char类型正好占用一个字节的形式,所以将其强制转化为char*类型就可以求出其大小了。

2:在上面指针的分析当中,(a+1)是指向下一个元素的首地址,那么我们还有一种思路就是这样的,将变量放入到一个数组当中,将(a+1)减去a就得到了变量的大小,再强制转化为字节形式就可以了。

下面是我的实现:

#include <stdio.h>

struct hello{
    char c1;
    int m;
    char c2;
};

int main(void)
{
    //我们需要求结构a的大小
    struct  hello a;

    //则将三个结构a放到数组中
    struct hello b[] = {a,a,a};

    //按照上面的思想进行求取
    int s = (char*)(b+1) - (char*)b;
    //输出结果没有问题
    printf("%d\n",s);

    return 0;
}

转载于:https://my.oschina.net/u/1051345/blog/416909

### 如何在 C 语言使用 `sizeof` 运算符获取数组的长度 在 C 语言中,`sizeof` 是一个用于计算数据类型或变量所占内存大小的关键字。当 `sizeof` 用于数组时,可以用来计算数组的总字节数,进而通过除以单个元素的大小来获取数组的长度[^1]。 #### 基本用法 对于一个在函数内部定义的数组,可以通过以下方式计算其长度: ```c int arr[] = {1, 2, 3, 4, 5}; int length = sizeof(arr) / sizeof(arr[0]); printf("Array length: %d\n", length); ``` 在上述代码中,`sizeof(arr)` 返回整个数组所占的字节数,`sizeof(arr[0])` 返回数组中单个元素的大小。通过 `sizeof(arr) / sizeof(arr[0])` 可以得到数组中元素的个数。 #### 在函数中使用 `sizeof` 的限制 当数组作为函数参数传递时,数组名会退化为指向数组首元素的指针。此时使用 `sizeof(arr)` 会返回指针的大小,而是整个数组的大小。例如: ```c #include <stdio.h> void printLength(int arr[]) { int length = sizeof(arr) / sizeof(arr[0]); printf("Length inside function: %d\n", length); } int main() { int arr[] = {1, 2, 3, 4, 5}; int length = sizeof(arr) / sizeof(arr[0]); printf("Length in main: %d\n", length); printLength(arr); return 0; } ``` 在 `main` 函数中输出的长度为 `5`,而在 `printLength` 函数中输出的长度则为 `1`(32 位系统)或 `2`(64 位系统),这是因为 `arr` 在函数参数中是一个指针,`sizeof(arr)` 返回的是指针的大小,而是数组的大小[^1]。 #### 解决方案 为了避免在函数中无法获取数组长度的问题,可以在调用函数时额外传递数组的长度作为参数: ```c #include <stdio.h> void printLength(int arr[], int size) { for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[] = {1, 2, 3, 4, 5}; int length = sizeof(arr) / sizeof(arr[0]); printf("Length in main: %d\n", length); printLength(arr, length); return 0; } ``` 在上述代码中,`length` 被作为参数传递给 `printLength` 函数,从而确保函数能够正确获取数组的长度。 #### 注意事项 - `sizeof` 是编译时运算符,其结果在编译阶段就已经确定。 - 对于动态分配的数组(如通过 `malloc` 分配的数组),`sizeof` 无法获取数组的长度,因为 `sizeof` 仅能返回指针的大小。 - 在函数中使用数组时,必须显式传递数组的长度,否则无法通过 `sizeof` 获取数组长度。 #### 示例输出 运行上述代码后,输出结果如下: ``` Length in main: 5 1 2 3 4 5 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值