C语言 --- sizeof() 7种使用详解


用了多年的c, sizeof几乎没怎么用过, 一直蒙查查的, 今天查了一下用法, 发现忽视了不知识呢,


预备知识:

  • char c='a' 与 'a',c是1字节的字符变量, 但'a'是占4字节的整形常量;
  • char *c,  c是地址, 指向的数据按1字节读取, 但c本身是指针类型, 无符号整型(u32), 用4字节存放的地址值;
  • 字节对齐,  内存为了高速地处理数据, 每次按32位读写, 数据存放时地址自动调整在能被对齐字节数整除的位置.

sizeof (  

关键字, 关键字, 关键字,  不是函数 ! 

编译时确定其值,  计算出x在内存中所占字节数. 

 所以, 括号内的赋值和函数, 不会被执行, 编译与执行, 没一分钱联系.

    1. sizeof ( 数值 )            

char c=8;
int  i=32;
printf("%ld", sizeof(c    ));  // 结果:1, 因为char就是1字节
printf("%ld", sizeof(c+i  ));  // 结果:4, i是4字节, 运算时c值被隐式转换成int, 运算值是4字节
printf("%ld", sizeof(c=c+i));  // 结果:1, 等同于(c), 编译时, 因为=不被执行, 所以=的右边只是个屁 

    2. sizeof ( 字符 )

// 小心, char和'a'在被=动作前, 是两个独立类型, 没关联
char c = 'a';  
printf("%ld", sizeof(c));      // 结果:1, char类型是1字节
printf("%ld", sizeof('a');    // C结果:4,C++结果:1
                               // C99的标准,    'a'是整型字符常量,常量!常量!常量!被看成是int型, 所以占4字节。
                               // ISO C++的标准,'a'是字符字面量  ,被看成是char型,所以占1字节。

    3. sizeof ( 字符串 )

printf("%ld", sizeof("abc");  // 结果:4,双引号会在尾部自动添加转义字符'\0',即数据0X00, 所以是4   
                               // 双引号作用: (1)字符串尾部加0, (2)开辟内存空间, (3)提取地址

    4. sizeof ( 数组 )

char a[50]="老师,早上好!";
printf("%ld", sizeof(p));      // 结果:50, 返回数组总字节大小

    5. sizeof ( 指针 )

// 小心, 指针是地址, 指向某数据空间, 地址常是4字节.
char *p="老师,早上好!";
printf("%ld", sizeof(p);      // 结果:4, 返回指针大小,指针本身就是一个无符号整型数. 不是所指向的内存空间的大小 
                              // char *a[8], 在数组内存放8个地址, 8个*4字节=32字节, 而不是8个*1字节=8字节

    6. sizeof ( 结构体 )    

// 字节对齐,为快速处理数据,内存是按32位读取写的,而不是一字节一字节地读写
// 结构体的首地址自动对齐至能被对齐字节数大小所整除。
// 结构体每个成员在结构体内的偏移地址都是成员大小的整数倍,否则, 在前方填充byte。
// 结构体的总大小为结构体对齐字节数大小的整数倍

struct T1{
    int   a;                  // 成员随意位置
    char  b;
    int   c;
    short d;
}t1;
printf("%ld", sizeof(t1);     // 结果:16, 4+4+4+4

struct T2{
    int   a;                  // 合理安排成员位置
    char  b;
    short d;
    int   c;
}t2;
printf("%ld", sizeof(t2);     // 结果:12, 4+4+4, 设计结构时,调整成员的位置,可节省存储空间。

    7. sizeof ( 函数 )

// 小心, 函数不执行
char Sum(int i, short s);
printf("%ld", sizeof(Hellow(32, 8));  // 结果:1, 只会判断返回类型的大小. 函数是不会执行的! 

如有错误, 望请回复指正~~

文章参考资料:

(1): CSDN博主「王二车」的原创文章,原文链接:https://blog.csdn.net/TSZ0000/article/details/82868929

(2) 理一理字节对齐的那些事, 理一理字节对齐的那些事 - 知乎


   

  • 188
    点赞
  • 636
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
C语言中,shutdown函数用于关闭套接字的读、写或读写两个方向上的操作。 函数原型为: ```c #include <sys/socket.h> int shutdown(int sockfd, int how); ``` 参数说明: - sockfd:需要关闭方向的套接字描述符。 - how:关闭方式,有如下三取值: - SHUT_RD:关闭套接字读取功能。 - SHUT_WR:关闭套接字写入功能。 - SHUT_RDWR:关闭套接字读取和写入功能。 函数返回值: - 成功返回0。 - 失败返回-1,并设置errno变量,表示错误原因。 示例代码: ```c #include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #define PORT 8888 int main() { int server_fd, new_socket, valread; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[1024] = {0}; char *hello = "Hello from server"; // 创建套接字文件描述符 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); return -1; } // 设置套接字选项 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt failed"); return -1; } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 绑定端口 if (bind(server_fd, (struct sockaddr *) &address, sizeof(address)) < 0) { perror("bind failed"); return -1; } // 监听端口 if (listen(server_fd, 3) < 0) { perror("listen failed"); return -1; } // 接受客户端连接 if ((new_socket = accept(server_fd, (struct sockaddr *) &address, (socklen_t *) &addrlen)) < 0) { perror("accept failed"); return -1; } // 读取客户端数据 valread = read(new_socket, buffer, 1024); printf("%s\n", buffer); // 发送消息给客户端 send(new_socket, hello, strlen(hello), 0); printf("Hello message sent\n"); // 关闭写入操作 shutdown(new_socket, SHUT_WR); // 读取剩余数据 valread = read(new_socket, buffer, 1024); printf("%s\n", buffer); return 0; } ``` 在上述示例代码中,我们通过调用shutdown函数关闭了套接字的写入操作,然后继续读取客户端发送的数据。这个过程可以用来模拟客户端和服务器之间的通信过程。
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值