sizeof 数组与指针

sizeof的定义:

sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。

MSDN上的解释为:

The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type(including aggregate types). This keyword returns a value of type size_t.

sizeof关键字提供与变量或类型(包括聚合类型)关联的存储量(以字节为单位)。此关键字返回一个size_t类型的值。看到返回,但不要认为这是一个函数。

对于sizeof的理解,sizeof:

首先是一个关键字,也是一个操作符,而非函数。

其次求长度,返回一个对象或者类型所占的内存字节数。

总结一下:sizeof更像一个特殊的宏,它是在编译阶段求值的。不要把sizeof当成函数,也不要看作一元操作符,把他当成一个特殊的编译预处理。

sizeof(数组),结果是数组所占的空间大小;

sizeof(指针),结果又是什么呢? sizeof(指针),其结果和操作系统有关,32位操作系统返回值4,64位操作系统返回值8。

再来理解这句话:sizeof求长度,返回一个对象或者类型所占的内存字节数。那么sizeof(指针),就是返回指针在内存中占用空间大小;

接着在问一个问题,不同的指针在操作系统中占用的空间大小是一样的吗?答案是肯定的,不同的指针类型在操作系统中占用的空间大小是一样的。

在写代码时,还会遇到对一个常量字符串求长度,例如:对123456字符串求长度,

printf("sizeof(123456)=%d\n", sizeof("123456"));

这个打印结果是7,是否超出了你的预期。对于sizeof("xxx"),对于""中的字符串,sizeof操作求长度,默认后面还有一个\0,所以实际的长度要+1。

printf("sizeof(1+1.2)=%d\n", sizeof(1+1.2));

 这个打印结果是8,是否又超出了你的预期。

sizeof(express),其中的express在编译过程中是不会被编译的,而是被替代类型。

     例如: int a = 1; sizeof(a=2);

     此时的express为a=2,在编译过程中被替换为sizeof(int),所以在执行完之后,a仍然是等于1。

所以sizeof(1+1.2) 在编译过程中被替换成double类型的,double占8个字节。

用一个程序来验证一下:

#include <stdlib.h>
#include <stdio.h>

typedef struct
{
    int a;
    char buf[20];
}Node_t;

int get_array_point_size(int *data)
{
    printf("\narray pointer size %d\n", sizeof(data));
    return 0;
}

int main()
{
    char *q=NULL;
    float *f=NULL;
    Node_t *node =NULL;
    
    int a[5]={1,2,3,4,5};
    int *p=a;
    
    printf("p = %p\n",p);
    int *ptr = (int *)(&a+1);

    printf("ptr=%p\n",ptr);
    printf("%d   %d\n",*(a+1),*(ptr-1));

    printf("sizeof(ptr-1) = %d\n",sizeof(ptr-1));


    printf("sizeof(q)=%d\n", sizeof(q));
    printf("sizeof(f)=%d\n", sizeof(f));
    printf("sizeof(node)=%d\n\n", sizeof(node));

    printf("sizeof(a)=%d\n", sizeof(a));
    printf("sizeof(*q)=%d\n", sizeof(*q));
    printf("sizeof(*f)=%d\n", sizeof(*f));
    printf("sizeof(*node)=%d\n", sizeof(*node));

    printf("sizeof(123456)=%d\n", sizeof("123456"));

    get_array_point_size(a);

    return 0;
}

//运行结果
root@ubuntu140453200:/mnt/external/root/test/linux_c$ ./sizeof_1
p  =0x7ffd7485fa10
ptr=0x7ffd7485fa24
2   5
sizeof(ptr-1)=8
sizeof(q)=8
sizeof(f)=8
sizeof(nood)=8

sizeof(a)=20
sizeof(*q)=1
sizeof(*f)=4
sizeof(*nood)=24
sizeof(123456)=7

array pointer size 8
root@ubuntu140453200:/mnt/external/root/test/linux_c$

补充说明,32位编译器,64位编译器的对数据类型的大小定义不一样。 

        

各位看官,看到这里可能有一个问题,如果是数组作为参数传入到函数,那么这个数组在函数内部进行sizeof求长度结果是什么? 结果也是8个字节。

这里面有一段指针的内容:

    int a[5]={1,2,3,4,5};
    int *p=a;
    
    printf("p = %p\n",p);
    int *ptr = (int *)(&a+1);

    printf("ptr=%p\n",ptr);
    printf("%d   %d\n",*(a+1),*(ptr-1));

    printf("sizeof(ptr-1) = %d\n",sizeof(ptr-1));

下面来讲一下这个指针:

int a[5] = {1, 2, 3, 4, 5}; 表示 a 是一个数组,里面有五个成员;

a 表示这个数组的首地址,

a[0] 表示数组的第一个元素,

&a 表示对数组的首地址进行取址操作,这个操作其实是二维操作,将 a 看做一个二维数组,即 a[][5],相当于a[0]

&a + 1  表示将数组a,看做一个二维数组,&a 表示二维数组的第一维度的首地址,&a + 1 表示第一维度的第二组的首地址,即 a[][5], 相当于 a[1]

ptr = (int *)(&a + 1) 表示将 ptr 指向了二维数组的 a[1], 把 a 看做一个二维数组。但是这个访问是非法的,产生越界了。如果直接访问ptr的内容,程序会挂掉。

(ptr - 1) 表示的就是 a[1][0] - 1 减去一个数组成员,即a[0][5],这个访问是合法的

所以最后打印的结果就是:

p  =0x7ffd7485fa10
ptr=0x7ffd7485fa24
2   5

  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数组名和指针sizeof是不同的。根据引用中的解释,数组名和指向该数组指针在地址上是相同的,但是它们的大小不同。数组名的sizeof返回的是整个数组的大小,而指针sizeof返回的是指针类型的大小。所以,sizeof数组名会返回整个数组的大小,而sizeof指针会返回指针类型的大小。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [探讨C++中数组名与指针的用法比较分析](https://download.csdn.net/download/weixin_38691256/14871672)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [C++/C中 sizeof(指针)和sizeof(数组名)的区别](https://blog.csdn.net/weixin_38383877/article/details/90922929)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [c 语言中的sizeof数组名)和sizeof(指针)](https://blog.csdn.net/Colorful_lights/article/details/79819682)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值