首页 > 其他分享 >sizeof 在函数使用中的问题

sizeof 在函数使用中的问题

时间:2024-07-06 19:26:11浏览次数:17  
标签:10 函数 countof buffer 数组 使用 大小 sizeof

使用 sizeof 来获取数组的大小在某些情况下是可以的,但在涉及到函数参数时可能会有一些问题。 使用 sizeof 获取数组大小

当数组在当前作用域内声明时,可以使用 sizeof 来获取数组的大小。例如:

#include <cstdio>

int main() {
    char buffer[10];
    printf("Size of buffer: %zu\n", sizeof(buffer)); // 输出:10

    return 0;
}

在这个例子中,sizeof(buffer) 返回的是数组的总大小(以字节为单位)。对于 buffer[10],返回值为 10。

sizeof 在函数参数中的限制

当数组作为参数传递给函数时,sizeof 可能无法按预期工作。原因是数组在函数参数中退化为指针,这时 sizeof 返回的是指针的大小,而不是数组的大小。

#include <cstdio>

void printSize(char buffer[]) {
    printf("Size of buffer in function: %zu\n", sizeof(buffer)); // 输出:指针的大小(通常为 8 或 4)
}

int main() {
    char buffer[10];
    printf("Size of buffer in main: %zu\n", sizeof(buffer)); // 输出:10

    printSize(buffer);

    return 0;
}

在这个例子中,sizeof(buffer) 在 main 函数中返回 10,但在 printSize 函数中返回的是指针的大小(在64位系统上通常是8,在32位系统上通常是4)。

使用 _countof 宏

Microsoft 提供了 _countof 宏,用于在编译时获取数组的元素个数。这个宏的实现通常是这样的:

#define _countof(array) (sizeof(array) / sizeof(array[0]))

_countof 宏可以正确地在编译时计算数组的大小:

#include <cstdio>

void printSize(char buffer[], size_t size) {
    printf("Size of buffer in function: %zu\n", size); // 输出传递的实际大小
}

int main() {
    char buffer[10];
    printf("Size of buffer in main: %zu\n", sizeof(buffer)); // 输出:10

    printSize(buffer, _countof(buffer));

    return 0;
}

在这个例子中,_countof(buffer) 返回数组的大小,结果是 10。

其实如果不想使用该方法,可以借鉴该方法,自己在函数外定义一个变量如 len=(sizeof(array) / sizeof(array[0]),然后通过传参的方式传入函数内部。

为什么选择 scanf_s 需要数组大小

scanf_s 需要数组大小作为额外参数来进行边界检查,确保不会发生缓冲区溢出。这是提高安全性的一个重要措施:

#include <cstdio>

int main() {
    char buffer[10];

    // 使用 scanf_s 读取字符串,并提供数组大小
    printf("Enter a string: ");
    scanf_s("%9s", buffer, (unsigned)_countof(buffer)); // 提供数组大小,防止溢出
    printf("You entered: %s\n", buffer);

    return 0;
}

在这里,_countof(buffer) 提供了数组的大小,确保 scanf_s 不会写入超过 buffer 容量的数据,从而防止缓冲区溢出

总结

• 在当前作用域内,使用 sizeof 可以正确地获取数组的大小。
• 当数组作为函数参数传递时,sizeof 会退化为指针大小,不再表示数组的实际大小。
• 使用 _countof 宏可以在编译时获取数组的元素个数,适用于许多需要数组大小的场景。
• scanf_s 等安全函数需要提供数组大小来防止缓冲区溢出。

标签:10,函数,countof,buffer,数组,使用,大小,sizeof
From: https://blog.csdn.net/weixin_46089415/article/details/140234178

相关文章

  • 使用c++实现图形化文件浏览
       代码中使用了SDL2库,需要先安装并正确配置相关的开发环境。还需要添加字体加载和处理的代码,为图方便,省略。#include<iostream>#include<SDL2/SDL.h>#include<SDL2/SDL_image.h>#include<vector>#include<string>#include<filesystem>constintSCREEN......
  • STM32封装ESP8266一键配置函数:实现AP模式和STA模式切换、服务器与客户端创建
    鱼弦:公众号【红尘灯塔】,CSDN博客专家、内容合伙人、新星导师、全栈领域优质创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)STM32封装ESP8266一键配置函数:实现AP模式和STA模式切换、服务器与客户端创建......
  • rsync使用教程
    1、rsync是什么rsync是一个在Unix/Linux环境下常用的工具,Windows上可以通过一些替代工具或者使用Cygwin环境来实现类似的功能。Cygwin在安装过程中,选择需要安装的组件时确保选择了rsync和openssh(如果需要通过SSH连接到其他服务器进行备份)。rsync的简单使用如下:rsync-avz......
  • ArcPy|使用ArcPy实现区域统(ZonalStatisticsAsTable)计并将统计结果添加到原有要素的属
    ArcPy|使用ArcPy实现按区域统计并将统计结果添加到原有要素的属性表​ 使用ArcPy快速实现按区域统计,并将统计结果添加到原有属性表,因为ArcPy的接口中并没有直接添加这一选项,这里是选择输出了一个中间dbf文件,再将中间dbf文件与原有要素连接来实现。#-*-coding:utf-8-*-"""P......
  • kvm使用安装
    1.安装前检查1.1.查看CPU是否支持VTcat/proc/cpuinfo|egrep'vmx|svm' 关防火墙和selinuxsystemctlstopfirewalldsetenforce0配置yum源先备份整理cd/etc/yum.repos.dmkdir-pbakmvCentOS*./bak配置阿里云yum源curl-o/etc/yum.repos.d/CentOS-Bas......
  • 非堆成加密是公私钥使用
    对称加密学习-CSDN博客加密算法学习-CSDN博客非对称加密算法使用一对密钥,包括一个公钥和一个私钥,它们是数学上相关联的,但公钥可以公开分享,而私钥必须保密。以下是使用非对称加密算法的一般步骤:密钥生成:用户首先生成一对密钥,包括一个私钥和一个公钥。私钥必须安全存储,不能......
  • rider使用libman
    问题rider没有libman的相关功能,需要使用cli安装Libmandotnettoolinstall-gMicrosoft.Web.LibraryManager.Cli#如果存在可以尝试更新dotnettoolupdate-gMicrosoft.Web.LibraryManager.Cli查看命令libman--help初始化cdnjs官网libmaninit安装j......
  • 深入Laravel事件系统:创建与使用事件的指南
    Laravel的事件系统是一种强大的机制,它允许你将应用程序的行为封装成事件,然后在适当的时候触发这些事件。这不仅有助于代码的解耦,还提高了应用程序的可维护性和可扩展性。本文将详细介绍如何在Laravel中创建和使用事件,包括事件的定义、监听器的编写、事件的触发以及事件队列......
  • Python以中心裁剪图片,一个中国大陆身份证的尺寸是88mm*55mm,通常使用的身份证像素分辨
    1#以中心裁剪图片2#一个中国大陆身份证的尺寸是88mm*55mm,通常使用的身份证像素分辨率是336*2563defcrop_image_by_center(input_image_path,width_mm=88,height_mm=55):4#打开图片5image=Image.open(input_image_path)6image=ImageOps.ex......
  • 阿里云 CLI 使用
    安装macOS:brewinstallaliyun-cliLinux:wgethttps://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgztarxzvfaliyun-cli-linux-3.0.16-amd64.tgzsudocpaliyun/usr/local/bin配置配置文件位置在~/.aliyun提前创建阿里云AccessKey|阿里云帮助中心......