当前位置:主页 > c/c++教程 > C语言sizeof运算符陷阱

聊聊C语言中sizeof运算符的一个陷阱

发布:2023-03-11 20:00:01 59


为找教程的网友们整理了相关的编程文章,网友石泰然根据主题投稿了本篇教程内容,涉及到c语言程序运算符sizeof、sizeof、c语言、C语言sizeof函数、C语言sizeof运算符陷阱相关内容,已被612网友关注,如果对知识点想更进一步了解可以在下方电子资料中获取。

C语言sizeof运算符陷阱

sizeof运算符通常用于获取变量或类型所占内存的大小(单位是字节)

#include 
 
struct D{
    char a;
    int b;
};
 
int main()
{
    int a = 0;
    struct D d;
    printf("sizeof(a)=%ld\n", sizeof(a));
    printf("sizeof(int)=%ld\n", sizeof(int));
    printf("sizeof(d)=%ld\n", sizeof(d));
    printf("sizeof(struct D)=%ld\n", sizeof(struct D));
    return 0;
}

运行程序输出:

sizeof(a)=4
sizeof(int)=4
sizeof(d)=8
sizeof(struct D)=8

使用此特性可以结合memset,对数据结构进行初始化:

#include 
#include 
 
struct D{
    char a;
    int b;
};
 
int main()
{
	D d;
	printf("before init:a=%d, b=%d\n", d.a, d.b);
	memset(&d, 0, sizeof(d));
	printf("after init:a=%d, b=%d\n", d.a, d.b);
    return 0;
}

运行程序输出:

before init:a=16, b=0
after init:a=0, b=0

不过在使用sizeof时需要注意,对于指针类型的变量,只会求值指针的大小,不会求值其指向内容的大小:

#include 
 
int main()
{
    char str[10] = {0};
    char* pStr = str;
    printf("sizeof(str)=%ld\n", sizeof(str));
    printf("sizeof(pStr)=%ld\n", sizeof(pStr));
    return 0;
}

运行程序输出:

sizeof(str)=10
sizeof(pStr)=8

这对于通过函数参数进行sizeof求值是一个陷阱:

#include 
#include 
 
void f(char *pStr)
{
	memset(pStr, 'a', sizeof(pStr));
	printf("pStr:%s sizeof(pStr)=%ld\n", pStr, sizeof(pStr));
}
 
int main()
{
    char str[10] = "123456789";
    printf("str:%s sizeof(str)=%ld\n", str, sizeof(str));
    f(str);
    return 0;
}

运行程序输出:

str:123456789 sizeof(str)=10
pStr:aaaaaaaa9 sizeof(pStr)=8

可见,在函数f内,通过指针pStr求值sizeof,获得的是指针的大小(64位系统上位8个字节),如果依据此指来初始化str,那么只能操作8个字节,也就导致了调用函数f后,str进入了一种混乱的状态,其内容为:aaaaaaaa9

Sizeof的作用非常简单:求对象或者类型的大小。然而sizeof又非常复杂,它涉及到很多特殊情况,本篇把这些情况分门别类,总结出了sizeof的10个特性:

(0)sizeof是运算符,不是函数;

(1)sizeof不能求得void类型的长度;

(2)sizeof能求得void类型的指针的长度;

(3)sizeof能求得静态分配内存的数组的长度!

(4)sizeof不能求得动态分配的内存的大小!

(5)sizeof不能对不完整的数组求长度;

(6)当表达式作为sizeof的操作数时,它返回表达式的计算结果的类型大小,但是它不对表达式求值!

(7)sizeof可以对函数调用求大小,并且求得的大小等于返回类型的大小,但是不执行函数体!

(8)sizeof求得的结构体(及其对象)的大小并不等于各个数据成员对象的大小之和!

(9)sizeof不能用于求结构体的位域成员的大小,但是可以求得包含位域成员的结构体的大小!

概述:

Sizeof是C/C++中的关键字,它是一个运算符,其作用是取得一个对象(数据类型或者数据对象)的长度(即占用内存的大小,以byte为单位)。其中类型包含基本数据类型(不包括void)、用户自定义类型(结构体、类)、函数类型。数据对象是指用前面提到的类型定义的普通变量和指针变量(包含void指针)。不同类型的数据的大小在不同的平台下有所区别,但是c标准规定所有编译平台都应该保证sizeof(char)等于1。关于sizeof的更多概述你可以在msdn总输入sizeof进行查询。

总结

到此这篇关于C语言中sizeof运算符的一个陷阱的文章就介绍到这了,更多相关C语言sizeof运算符陷阱内容请搜索码农之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持码农之家!


参考资料

相关文章

  • VScode上配置 c语言环境的图文教程

    发布:2022-04-16

    这篇文章主要介绍了配置VScode c语言环境,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下


  • C指针原理教程之C快速入门

    发布:2022-04-04

    C语言作为大学编程或者计算机专业的一门必修课,把很多初学编程的小伙伴都难住了,感觉无从下手,今天呢,我们来简单介绍下,如何快速入门C语言


  • 详解C语言内核中的链表与结构体

    发布:2023-03-03

    Windows内核中是无法使用vector容器等数据结构的,当我们需要保存一个结构体数组时,就需要使用内核中提供的专用链表结构。本文分享了几个内核中使用链表存储多个结构体的通用案例,希望对你有所帮助


  • C语言中atoi函数模拟实现详析

    发布:2023-03-04

    atoi函数功能是将数字字符串转换为整数,比如数字字符串"12345"被atoi转换为12345,数字字符串"-12345"被转换为-12345,下面这篇文章主要给大家介绍了关于C语言中atoi函数模拟实现的相关资料,需要的朋友可以参考下


  • C语言:队列的实现全解析

    C语言:队列的实现全解析

    发布:2022-12-06

    给网友们整理关于C语言的教程,队列(Queue)与栈一样,是一种线性存储结构,它具有如下特点:队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构。在队尾添加元素,在队头删除元素


  • C语言扫雷游戏实例代码

    发布:2021-06-02

    这篇文章主要为大家详细介绍了C语言代码实现扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下


  • C语言驱动开发内核特征码扫描PE代码段

    发布:2023-03-07

    这篇文章主要为大家介绍了C语言驱动开发内核特征码扫描PE代码段,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪


  • 12个C语言必背实例分享

    发布:2023-03-09

    这篇文章主要和大家介绍12个C语言中必背的实例,文中的示例代码讲解详细,对我们了解和掌握C语言有一定的帮助,感兴趣的小伙伴快跟随小编一起了解一下


网友讨论