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

1.sizeof是运算符,跟加减乘除的性质其实是一样的,在编译的时候进行执行,而不是在运行时才执行。
那么如果编程中验证这一点呢?ps:这是前两天朋友淘宝面试的一道题,小编理解:

复制代码 代码如下:

#include<iostream>

using namespace std;

int main()
{
    int i=1;
    cout<<i<<endl;
    sizeof(++i);
    cout<<i<<endl;
    return 1;
}

输入结果为 1  
               1
sizeof中的++i 的副作用并没有显示出来,原因只可能有一个,在编译的时候sizeof执行以后将++i 处理了,++i 的副作用因此被消除了。如果sizeof 是在运行时进行的话,则肯定要注意++i 。实际上sizeof的实现应该是用宏来做的,宏在编译时进行执行。具体实现可以参考下面。

2.sizeof('a')在C语言中的结果是4,在C++中结果是1,看过某篇文章说C中sizeof侧重于“数”,而C++中sizeof更侧重于“字符”。

3.文章中讲了两个用宏实现sizeof的经典应用

复制代码 代码如下:

//适用于非数组
#define _sizeof(T) ((size_t)((T*)0 + 1))
//适用于数组
#define array_sizeof(T) ((size_t)(&T+1)-(size_t)(&T))

先举两个小例子说明两个宏的应用,对于第一个如 _sizeof(int); 的结果就是4;对于第二个先声明一个大小为4的数组int a[4];那么array_sizeof(a)结果为16.

对于非数组的宏定义,先是将0转换为T*类型的指针所指向的地址(此时地址为0)。然后对T类型的地址加1,相当于加上了T类型的大小(即得到了非数组T的大小)。前面的size_t只是将地址转化为int型的整数返回。

一个简单的例子:int* p; p=p+1; --------p是一个int*类型的指针, p+1在地址空间上相当于加上了4个字节。

对于数组的宏定义,类似于非数组的宏定义,为了方便理解,这里可以把数组T看成一个用户自定义的类型,&T表示数组类型的指针,对于数组类型指针加1相当于在地址上加上了该数组大小。由于是用户自定义的类型所以不能强制将0转化为数组类型的地址,只能用加1后的地址减去之前的地址,得到的差值就是数组本身所占的字节大小。

时间: 2024-08-02 10:50:14

对C语言中sizeof细节的三点分析介绍_C 语言的相关文章

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

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

详解C语言中scanf函数使用的一些注意点_C 语言

 (一)基本介绍 Scanf是系统自带的函数,声明包含在stdio.h文件中,因此要是有该函数,必须加载#include<stdio.h>头文件.当执行到scanf函数时,程序就暂停等待用户输入,该函数只接受变量的地址,格式为&变量名.是一个阻塞式的函数,2用户输入完毕后,则将值赋值给变量,至此函数调用完毕.敲回车键告知计算机键入完毕. (二)使用注意 ①. 使用scanf函数输入一个字符变量.Char a; scanf("%c",&a); ②. 同时输入多

C语言中的fscanf()函数与vfscanf()函数使用_C 语言

C语言fscanf()函数:输入函数(比较常用)头文件: #include <stdio.h> 定义函数: int fscanf(FILE * stream, const char *format, ...); 函数说明:fscanf()会自参数stream 的文件流中读取字符串, 再根据参数format 字符串来转换并格式化数据.格式转换形式请参考scanf(). 转换后的结构存于对应的参数内. 返回值:成功则返回参数数目, 失败则返回-1, 错误原因存于errno 中. 范例 #inclu

详解C语言中strcpy()函数与strncpy()函数的使用_C 语言

C语言strcpy()函数:复制字符串 头文件:#include <string.h> 定义函数: char *strcpy(char *dest, const char *src); 函数说明:strcpy()会将参数src 字符串拷贝至参数dest 所指的地址. 返回值:返回参数dest 的字符串起始地址. 附加说明:如果参数 dest 所指的内存空间不够大,可能会造成缓冲溢出(buffer Overflow)的错误情况,在编写程序时请特别留意,或者用strncpy()来取代. 范例 #i

对比C语言中memccpy()函数和memcpy()函数的用法_C 语言

C语言memccpy()函数:复制内存中的内容头文件: #include <string.h> 定义函数: void * memccpy(void *dest, const void * src, int c, size_t n); 函数说明:memccpy()用来拷贝src 所指的内存内容前n 个字节到dest 所指的地址上.与memcpy()不同的是,memccpy()会在复制时检查参数c 是否出现,若是则返回dest 中值为c 的下一个字节地址. 返回值:返回指向dest 中值为c 的下

详解C语言中free()函数与getpagesize()函数的使用_C 语言

C语言free()函数:释放动态分配的内存空间头文件: #include <stdlib.h> free() 函数用来释放动态分配的内存空间,其原型为: void free (void* ptr); free() 可以释放由 malloc().calloc().realloc() 分配的内存空间,以便其他程序再次使用. [参数说明]ptr 为将要释放的内存空间的地址. free() 只能释放动态分配的内存空间,并不能释放任意的内存.下面的写法是错误的: int a[10]; // ... fr

快速学习C语言中for循环语句的基本使用方法_C 语言

对于某个特定任务我们可以采用多种方法来编写程序.下面这段代码也可以实现前面的温度转换程序的功能:#include <stdio.h> /*打印华氏温度-摄氏温度对照表*/ main() { int fahr; for (fahr = 0; fahr <= 300; fahr = fahr + 20) printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32)); } 温度的下限.上限和步长都是常量, printf 函数的第三个参数必

浅析C语言中strtol()函数与strtoul()函数的用法_C 语言

C语言strtol()函数:将字符串转换成long(长整型数)头文件: #include <stdlib.h> strtol() 函数用来将字符串转换为长整型数(long),其原型为: long int strtol (const char* str, char** endptr, int base); [参数说明]str 为要转换的字符串,endstr 为第一个不能转换的字符的指针,base 为字符串 str 所采用的进制. [函数说明]strtol() 会将参数 str 字符串根据参数 b

详解C语言中accept()函数和shutdown()函数的使用_C 语言

C语言accept()函数:接受socket连线头文件: #include <sys/types.h> #include <sys/socket.h> 定义函数: int accept(int s, struct sockaddr * addr, int * addrlen); 函数说明:accept()用来接受参数s 的socket 连线. 参数s 的socket 必需先经bind().listen()函数处理过, 当有连线进来时accept()会返回一个新的socket 处理代