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

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

#include <stdio.h>

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 <stdio.h>
#include <string.h>

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 <stdio.h>

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 <stdio.h>
#include <string.h>

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运算符陷阱内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言位运算和sizeof运算符详解

    位运算和sizeof运算符 C语言中提供了一些运算符可以直接操作整数的位,称为位运算,因此位运算中的操作数都必须是整型的.位运算的效率是比较高的,而且位运算运用好的话会达到意想不到的效果.位运算主要有6种:与(&),或(|),取反(~),异或(^),左移(<<),右移(>>). 1.位运算中的类型转换 位运算都必须进行Integer Promotion.在进行运算之前,都必须将char型.short型的数据转换为int或者unsigned int型再参与运算. 如下面这段程

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

    sizeof运算符通常用于获取变量或类型所占内存的大小(单位是字节) #include <stdio.h> 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&qu

  • C语言中sizeof()与strlen()的区别详解

    前言 sizeof()和strlen()经常会被初学者混淆,但其中有有很大区别: sizeof() 1. sizeof()[操作数所占空间的字节数大小]是一种c中的基本运算符. 可以以类型.指针.数组和函数等作为参数. 头文件类型为unsigned int. 运算值在编译的时候就出结果,所以可以用来定义数组维数. char a[5]="123"; int b=sizeof(a);//b=5 int c=strlen(a);//c=3 sizeof()是一种单目操作符,是用来计算你所使用

  • C语言中sizeof函数踩过的坑总结

    sizeof很简单,但是却很容易令人踩坑. 正文 先来看这样一段代码 int main() { int i=2; printf("%d\n",sizeof(i++)); printf("%d\n",i); return 0; } 非常简单的一段代码 当时我认为答案应该是 4 3 可是结果却是出乎我的意料了 这是为什么呢? 下面来仔细说一下 通过调试观察虽然确实有i++这么一句代码,但是却没有实现.说到这里很多人可能犯了和我一样的错误,认为sizeof是一个函数. 其

  • 详解C语言中sizeof如何在自定义函数中正常工作

    1.在main函数中,sizeof是可以正常工作的,比如: int main() { int n[5]; printf("input: \n"); int i ; for(i = 0; i < 5; i++) { scanf("%d",n + i); } int len = sizeof(n)/sizeof(n[0]); printf("%d\n",len); return 0; } 2.但是在自定义函数中就不可以了,如下: #includ

  • C语言中sizeof函数的基本使用总结

    前言 C语言中的sizeof是一个很有意思的关键字,经常有人用不对,搞不清不是什么.我以前也有用错的时候,现在写一写,也算是提醒一下自己吧. sizeof是什么 sizeof是C语言的一种单目操作符,如C语言的其他操作符++.--等,sizeof操作符以字节形式给出了其操作数的存储大小.操作数可以是一个表达式或括在括号内的类型名.这个操作数不好理解对吧?后面慢慢看就明白了.sizeof的返回值是size_t,在64位机器下,被定义为long unsigned int. sizeof函数的结果:

  • 深入聊聊C语言中的Const关键字

    目录 前言 01const简述 02常量的应用 常量作为函数的参数 C++中应用加const 03#define和const 总结 前言 const是一个C语言的关键字,它限定一个变量不允许被改变.使用const在一定程序上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解别人的程序有所帮助. 01const简述 下面简单描述一下const,基本都是教科书的知识.const修饰的变量,其值存放在只读数据段中,其值不能被改变.称为只读变量.关于什么是数据段,什么

  • C语言中sizeof()与strlen()函数的使用入门及对比

    sizeof()函数 1,是什么?     sizeof其实就是一个运算符,和那些+,-一样的东西,在程序编译的时候进行解析转换.虽然我们经常见到sizeof后面跟着个小括号,长得和函数差不多,但它和函数完全是两码事. 2,有什么用?     sizeof其实就是用于告诉我们编译器在为某一特定数据或者某种数据类型的数据在存储空间中开辟空间时,开辟的空间大小,以字节为单位. 3,怎么用?     sizeof(类型),或者sizeof(变量)都可以,得到的就是类型或者变量的存储空间.当对变量用的时

  • 对C语言中sizeof细节的三点分析介绍

    1.sizeof是运算符,跟加减乘除的性质其实是一样的,在编译的时候进行执行,而不是在运行时才执行.那么如果编程中验证这一点呢?ps:这是前两天朋友淘宝面试的一道题,小编理解: 复制代码 代码如下: #include<iostream> using namespace std; int main() {     int i=1;     cout<<i<<endl;     sizeof(++i);     cout<<i<<endl;    

  • 聊聊R语言中Legend 函数的参数用法

    如下所示: legend(x, y = NULL, legend, fill = NULL, col = par("col"), border = "black", lty, lwd, pch, angle = 45, density = NULL, bty = "o", bg = par("bg"), box.lwd = par("lwd"), box.lty = par("lty")

  • 浅谈C语言中的sizeof()和strlen()的区别

    目录 sizeof() strlen 补一个注意事项: sizeof()和strlen()经常会被初学者混淆,但其中有有很大区别: sizeof() 1. sizeof()[操作数所占空间的字节数大小]是一种c中的基本运算符.可以以类型.指针.数组和函数等作为参数.返回值类型为unsigned int 运算值在编译的时候就出结果,所以可以用来定义数组维数. char a[5]="123"; int b=sizeof(a);//b=5 int c=strlen(a);//c=3 size

随机推荐