编译时计算静态数组大小技巧

C++ sizeof()详解 总之,sizeof()是一个非常强大的工具,它在内存管理、性能优化和多平台开发中扮演着关键角色。 阅读详情

通过一个函数模板来实现编译时计算静态数组大小:


模板声明解析

template <typename T, size_t N>
char(&ArraySizeHelper(T(&array)[N]))[N];

这是一个函数模板声明,分解来看:

  1. 模板参数:

    • typename T:数组元素的类型
    • size_t N:数组的大小(非类型模板参数)
  2. 函数参数:

    • T(&array)[N]:这是一个对数组的引用,保留了数组类型信息(包括元素类型 T 和大小 N)
  3. 返回类型:

    • char(&)[N]:返回一个对 char[N] 数组的引用

工作原理

这个模板的核心技巧是:

  1. 通过引用传递数组(保留数组大小信息)
  2. 利用模板参数推导自动获取数组大小 N
  3. 返回一个与数组大小 N 相关的类型(char[N] 的引用)

典型用法

通常与 sizeof 结合使用来计算数组元素个数:

#define ARRAY_SIZE(arr) (sizeof(ArraySizeHelper(arr)))

使用示例:

int arr[10];
size_t count = ARRAY_SIZE(arr);  // 得到 10

为什么这样设计?

  1. 编译时计算:所有计算在编译期完成,零运行时开销
  2. 类型安全:
    • 如果传入指针而非数组,编译会失败(因为无法匹配模板)
    • 防止了 sizeof(arr)/sizeof(arr[0]) 在指针情况下的错误计算
  3. C++03兼容:这是在 C++11 的 constexpr 和 std::array 之前常用的技巧

现代C++替代方案

在 C++11 及以后,更推荐使用:

// 方法1:使用 std::array
std::array<int, 10> arr;
constexpr size_t count = arr.size();

// 方法2:使用 constexpr 函数
template <typename T, size_t N>
constexpr size_t array_size(T (&)[N]) { return N; }

总结

这个模板是经典的 C++ 模板元编程技巧,它:

  • 利用模板参数推导获取数组大小
  • 通过返回类型携带大小信息
  • 与 sizeof 配合实现安全的数组大小计算
  • 在传统 C++ 中是实现编译时数组大小计算的优雅解决方案
C语言中的一维数组大小:如何理解与计算 / 定义一个包含5个整数元素的数组i < 5;📌输出上面定义了一个包含5个元素的整数数组,并且为每个元素赋值。数组元素个数:数组的大小是由它包含的元素个数决定的。数组所占字节数:通过sizeof操作符,可以获得整个数组的总字节数。动态数组:动态数组的大小在运行时确定,无法使用sizeof获取其大小,需通过其他方式来记录。理解一维数组的大小对于C语言程序员来说是至关重要的,它帮助你更高效地管理内存和操作数据。 阅读详情

相关推荐

动态数组与静态数组-内存管理与性能对比

在数据结构的选择上,动态数组和静态数组各有优缺点。静态数组适合用于内存需求固定且性能要求较高的场景,但在数据量大或不确定的情况下,可能会导致内存浪费或无法存储更多的数据。而动态数组则更为灵活,能够根据需要动态扩容,但其性能和内存管理较为复杂,扩容操作可能导致性能下降。了解两者的优劣势,以及在具体场景中的适用性,能帮助开发者做出最适合的选择。

一键难忘的博客 3133

数组的大小

两种方法 1. chromium中得到数组的大小使用如下宏【1】---- 使用数组的引用 template char (&ArraySizeHelper(T (&array)[N]))[N]; #define arraysize(array) (sizeof(ArraySizeHelper(array))) 2.stdlib.h中_countof()宏【2】----

finding的专栏 1771

优化天气预测代码:循环与数组边界常量的编译时使用

本文探讨了在天气预测优化中,通过使用编译时常量来控制循环和数组边界以提升性能的策略。介绍了使用Intel编译器特定的对齐指令、循环重构技术以及如何根据不同的计算需求选择性地暴露数组维度,同时利用编译器开关来优化代码。通过实验验证,展示了编译时常量如何在保持代码灵活性的同时,提高向量化效率,最终显著提升了执行速度。

weixin_42593701的博客 493

由chrome源码中的arraysize想到的

在网上看到一段出自chrome的求数组长度的源代码: templatetypename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N]; #define arraysize(array) (sizeof(ArraySizeHelper(array))) google为什么不使用我们一般求数组长度的方法:

Ericdm的专栏 761

【效率手册】Kylin-Desktop-V10-SP1 麒麟系统核心组件实战——从入门到精通的6个关键场景

本文针对Kylin-Desktop-V10-SP1麒麟系统用户,通过文件管理、系统监视、设置优化等6个核心场景实战,深度解析如何高效运用系统内置工具解决文件混乱、性能卡顿、外设驱动等实际问题,帮助用户从功能认知跃升至场景化应用,真正释放国产操作系统的生产力潜能。

weixin_29208327的博客 118

UE5热更新(通过Pak包加载关卡资源,并添加到流关卡)

请先阅读我上一篇文章)**

xialuhui的博客 6456

C语言计算数组大小和数组长度的几种方式

C语言计算数组大小和数组长度的几种方式

OnlyLoveCsdn的博客 258

汽车以太网- IEEE 802.3标准

关于汽车以太网,大家看到最多的标准大概就是IEEE802.3bw,也就是我们车内使用的百兆以太网,专业称呼是100BASE-T1,该标准是车内百兆以太网的物理层协议,是我们学习汽车以太网必须要了解的协议。在正式了解协议之前,我们先介绍下什么是IEEE802.3标准。............

weixin_39974126的博客 7106

计算数组的长度

在chromium中有计算数组长度的宏 arraysize template char (&ArraySizeHelper(T (&array)[N]))[N]; // That gcc wants both of these prototypes seems mysterious. VC, for // its part, can't decide which to use (anothe

cwq水域 的专栏 1066

从零构建知识图谱:本体工程与知识建模实战指南

本文是一份从零构建知识图谱的实战指南,重点阐述了知识建模与本体工程的核心地位。文章详细介绍了如何使用Protégé工具进行本体设计,包括定义领域、复用现有本体、构建类层次与属性约束,并讲解了如何利用D2RQ工具将关系数据库数据转换为RDF三元组,最终通过Apache Jena Fuseki搭建SPARQL端点进行知识查询与推理,让知识图谱真正“活”起来。

weixin_29057695的博客 568

Palantir如何利用Ontology构建企业级数据地图

Palantir通过"本体论"(Ontology)技术构建动态数据地图,将多源异构数据转化为可操作的业务知识网络。该技术突破传统ETL模式,建立覆盖全组织的语义层,将原始数据映射为"客户""订单"等业务对象及其关联关系,形成可推理的语义网络。核心Foundry平台提供本体管理工具(OMA)和开发套件(OSDK),支持从数据连接到应用开发的全流程。虽然采用专有实现而非标准本体语言,但该架构成功解决了数据孤岛问题,赋能复杂决策分析

Learning 1788

如何获取C++ Array的大小

参考自chromium的处理方法如下:template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N]; #define arraysize(array) (sizeof(ArraySizeHelper(array)))范例:#include <iostream>template <typename T, size_t

wangruitao1991的专栏 2721

论文阅读:NeurIPS 2024 JailbreakBench: An Open Robustness Benchmark for Jailbreaking Large Language Model

论文指出评估越狱攻击存在挑战,如缺乏评估标准、成本和成功率计算方法不一致、许多研究无法复现。为解决这些问题,作者提出了JailbreakBench,这是一个开源基准测试,包含以下组件:持续更新的越狱提示库(jailbreak artifacts)。包含100种行为的越狱数据集,符合OpenAI的使用政策。标准化的评估框架,包括威胁模型、系统提示、聊天模板和评分函数。跟踪各种LLMs攻击和防御性能的排行榜。

CSPhD-winston的博客 1431

关于sizeof 和 strlen的区别

1. 编译时计算运算符sizeof,可用类型或变量做参数,计算占用内存的大小。sizeof后若是类型必须加括弧,若是变量名可不加括弧。sizeof(x)可用来定义数组维数。如:printf("%d\n", sizeof(short));输出的结果为短整型的长度2。用结构类型或变量做参数时,sizeof 返回实际的大小,当用于静态数组时,sizeof 返回全部数组的尺寸。sizeof 操作符不能返

dd916的专栏 237

基于MATLAB实现语音信号MFCC特征提取(附完整代码)

你有没有想过你的智能手机是如何理解语音指令的?或者 Alexa 和 Siri 等语音助手如何处理您的命令?这种卓越能力背后的机制在很大程度上归功于一种称为 Mel 频率倒谱系数 (MFCC) 的方法。语音识别技术允许机器解释人类语音,将口语转换为计算机可以操纵的格式。这项技术对于开发交互式和响应式 AI 至关重要,例如声控助手、自动化客户服务系统和实时翻译服务。MFCC 代表 Mel 频率倒谱系数。这是用于自动语音和说话人识别的功能。

baidu_34971492的博客 1313

【数据分享】12.5米分辨率DEM地形数据(分省)

该数据来源于NASA地球科学数据网站(https://nasadaacs.eos.nasa.gov/),是ALOS卫星获取的高精度地形数据。该数据由于精度高,包括全省范围的数据和省内每个城市范围的数据!

JData_Engineer的博客 2171

1. C语言静态数组与动态数组

1. C语言静态数组与动态数组

2402_86998005的博客 931

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C/C++数据结构之静态数组

静态数组是C/C++中一种基础的数据结构,它允许用户在编译时便确定数组的大小,并分配固定数量的连续存储空间来存放相同类型的元素。静态数组的主要特点是:其大小在声明时就必须指定,且在其生命周期内保持不变。这也意味着,一旦定义了一个静态数组,就不能改变它的大小,或重新分配内存。

hope_wisdom的技术博客 2324

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

对于c++中数组的最大长度的理解

可能很多人都有这样一个疑问:数组的最大可定义长度到底是多少? 网上众说纷纭:有些说跟内存大小,或者说栈大小、堆大小什么的。 今天在这里总结一下。首先,如果要确定一个数组的最大长度,我们需要知道它的数据类型,因此,数组的数据类型是其中一个限制因素。因为不同数据类型的元素大小不同。很显然(我们假设int为4字节,char为1字节),数据类...

二十四桥明月夜的博客 2万+

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

c语言数组大小不确定_这些装B式C语言技巧你会吗?

c语言C语言常常让人觉得它所能表达的东西非常有限。它不具有类似第一级函数和模式匹配这样的高级功能。但是C非常简单,并且仍然有一些非常有用的语法技巧和功能,只是没有多少人知道罢了。一指定的初始化很多人都知道像这样来静态地初始化数组:C99标准实际上支持一种更为直观简单的方式来初始化各种不同的集合类数据(如:结构体,联合体和数组)。这些c语言二数组我们可以指定数组的元素来进行初始化。这非常有用,特别是...

weixin_39669769的博客 962

C++14 constexpr数组实战:编译时计算与零开销抽象

constexpr是C++中实现编译时计算的核心机制,它允许在编译阶段完成表达式的求值,从而将计算从运行时提前。其原理在于编译器对常量表达式的识别与求值,这为程序带来了显著的性能优势,实现了零开销抽象。在工程实践中,这项技术常用于生成查找表、配置数组等场景,能有效提升高频计算和嵌入式系统的效率。本文聚焦于C++14对constexpr的增强,特别是其与数组数据结构的结合,通过具体示例展示了如何利用循环、控制流等新特性,在编译时动态生成和操作数组内容,从而替代传统的宏或硬编码方式。

weixin_33762130的博客 359

C 语言静态数组与动态数组

静态数组的生命周期与作用域相关,而动态数组的生命周期由程序员控制。在使用动态数组时,需要注意合理地分配和释放内存,以避免内存泄漏和访问无效内存的问题。

学习日常分享 1289

C++ : 静态数组内存不需要释放的原因

C++ : 静态数组内存不需要释放的原因

C++ JAVA的专栏 1687

【Julia入门】4.4 静态数组——《Julia全栈工程师》

虽然Julia标准库中没有直接提供静态数组的实现,但开发者可以通过使用元组或自定义类型来模拟静态数组的功能。这些静态数据结构在性能优化和内存管理方面具有独特优势,特别是在需要处理固定大小数据或进行高性能计算的场景中。通过合理利用静态数组的特性,开发者可以编写出更加高效、可靠的代码。👨‍💻博主Python老吕评论,您的举手之劳将对我提供了无限的写作动力!🤞') # 每日一码,用Python跟世界说Hello,World!🔥《Python全栈工程师》《跟老吕学MySQL》《Python游戏开发实战讲解》

Python老吕的博客 1337

静态数组——为Julia带来速度与效率的神器

在寻找一种能够提高你的Julia代码性能,并且拥有灵活内存管理的库吗?那么,让我们一起探索一下 StaticArrays —— 这个旨在实现静态大小数组的优秀开源项目。 ## 项目介绍 StaticArrays 是一个专为Julia设计的库,它提供了一种框架来创建类型定义尺寸的静态数组。这些数组不仅可以用于常见的数组和线性代数操作,而且由于其尺寸信息可从类型推断,因此在处理小型数据集时,它们的

gitblog_00053的博客 444

sizeof 运算所得的值是在编译时还是运行时确定?

《C语言程序设计》中对sizeof的描述:C语言提供了一个编译时(compile-time) 一元运算符 sizeof,它可以用来计算任一对象的长度。 表达式sizeof 对象以及sizeof(类型名)将返回一个整型值,它等于指定对象或类型占用的存储空间字节数。 依据上述描述,可以得出结论sizeof的值是在编译时确定的,而非运行期确定。 如一下举例代码: // 需在C99标准的编译器下编译, ANSI C (即C89)下编译不通过 #include <stdio.h> #include &lt

qq_37535749的博客 5501
上一篇: 为什么C++只能通过指针或引用来使用(动态)多态?
下一篇: /proc/<pid>/maps文件格式详解
抓饼先生
博客等级 码龄14年 136粉丝 114原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

抓饼先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值