文章首发及后续更新:https://mwhls.top/1975.html
新的更新内容请到mwhls.top查看。
无图/无目录/格式错误/更多相关请到上方的文章首发页面查看。

stackoverflow热门问题目录

如果翻译有问题,麻烦评论提醒一下,谢谢。

如何确定C的数组的大小?

  • Mark Harrison 提问:

    • 我该如何确定C里面数组的大小?
    • 即数组里面能容纳多少个元素?
  • 22 回答:
    • Mark Harrison - 1394 位用户认为有用:

      • 摘要:

        • int a[17];
        • size_t n = sizeof(a)/sizeof(a[0]);
      • 完整答案:
      • 数组所占空间的大小(字节),可以通过sizeof操作来确定。
        • int a[17];
        • size_t n = sizeof(a)/sizeof(a[0]);
      • 在我的计算机中,int占4个字节,所以n等于68。
      • 数组能容纳元素的个数,可以通过数组总大小除以数组元素大小来确定。数组元素的大小可以用它的类型大小表示,像这样:
        • int a[17];
        • size_t n = sizeof(a) / sizeof(int);
      • 就可以得到正确的答案(68 / 4 = 17),但如果类型改变且又忘记改变sizeof(int)里的int,那就会出现个讨厌的bug。
      • 所以最好是将sizeof(a[0])作为除数,或者是sizeof(*a),即数组第一个元素的大小。
        • int a[17];
        • size_t n = sizeof(a) / sizeof(a[0]);
      • 另一个挺方便的方法,是定义一个宏,并将数组名参数化,像这样:
        • #define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
        • int a[17];
        • size_t n = NELEMS(a);
    • Elideb - 883 位用户认为有用:

      • 在处理不是作为函数参数的数组时,sizeof的方式的确没错。数组作为函数的参数时会被视为指针,所以sizeof将会返回指针的大小,而不是数组的大小。
      • 因此,这个方法在函数内部没有效果。而为了获知数组的大小,最好再加一个size_t size作为函数的参数。
      • 例如下面的代码测试中所示,
        • 对于作为参数的数组指针,它返回的是Int指针的大小,
        • 而在函数外部对数组求大小,返回的是整个数组占据的大小,
        • 在译者的电脑(Windows 64位)中,int元素的大小是4,而int指针的大小是8,
        • 即便不是作为参数,而是新定义一个指针指向数组,亦是如此,
        • 这也解释了为什么答主的64位Linux显示Length of parameter等于2而不是1,
        • 因为8 / 4 = 2,
        • 这个问题让译者在LeetCode上纠结了一会:
        • #include <stdio.h>
        • #include <stdlib.h>
        • void printSizeOf(int intArray[]);
        • void printLength(int intArray[]);
        • int main(int argc, char* argv[])
        • {
        • int array[] = { 0, 1, 2, 3, 4, 5, 6 };
        • printf("sizeof of array: %d\n", (int) sizeof(array));
        • printSizeOf(array);
        • printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
        • printLength(array);
        • }
        • void printSizeOf(int intArray[])
        • {
        • printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
        • }
        • void printLength(int intArray[])
        • {
        • printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
        • }
      • 在64位Linux系统中的输出:
        • sizeof of array: 28
        • sizeof of parameter: 8
        • Length of array: 7
        • Length of parameter: 2
      • 在32位Linux系统中的输出:
        • sizeof of array: 28
        • sizeof of parameter: 4
        • Length of array: 7
        • Length of parameter: 1
    • Magnus Hoff- 144 位用户认为有用:

      • 值得一提的是,sizeof在处理指向数组的指针时并没有效果,哪怕它指向的是数组的首位,因为编译器把数组中的单个元素当做指针来对待。因为一个指针并不会“记得”任何关于它被初始化成数组的事。

        • int a[10];
        • int* p = a;
        • assert(sizeof(a) / sizeof(a[0]) == 10);
        • assert(sizeof(p) == sizeof(int*));
        • assert(sizeof(*p) == sizeof(int));
    • unwind - 51 位用户认为有用:
      • sizeof是我知道最好的技巧,不过在括号的使用上,有一个很小但很重要的改变(对我来说,这个是最令我烦恼的)。
      • 维基百科的条目中解释的很清楚,C的sizeof不是一个函数,而是一个运算符。因此,并不需要在参数旁边加括号,除非这个参数是个类型名称。这很容易记下来,因为它使得参数看起来像个强制转换表达式,也使用括号的那种。
      • 所以:如果你这么定义数组:
        • int myArray[10];
      • 你可以这样来求它的元素个数:
        • size_t n = sizeof myArray / sizeof *myArray;
      • 这对我来说,比带括号的形式好理解多了。我也赞成在除法的右边使用星号,因为这比用下标要简洁。
      • 当然,这都是编译时的,所以不用担心除法会影响程序的性能。所以尽可能的用这种形式。
      • 最好将sizeof用在实际对象里,而不是类型,因为这样不用担心造成bug或写成错误的类型。
      • 例如,假设你有一个函数,通过输出一些字节流数据的函数。我们调用send(),并且将参数设为一个指向待发送对象的指针,以及这个对象占据的字节数。所以,原型变为:
        • void send(const void *object, size_t size);
      • 需要发送一个整型时,可以这样做:
        • int foo = 4711;
        • send(&foo, sizeof (int));
      • 现在,你已经知道了一个能搬起石头砸自己的脚的办法,即在两个地方制定foo的类型。如果只有一个改变而另一个没有,代码会出错。因此,习惯这么做:
        • send(&foo, sizeof foo);
      • 现在没问题了。没错,你可以复制变量名,但如果你改变了它,很可能会被编译器检测出错。

How do I determine the size of my array in C?

  • Mark Harrison asked:

    • How do I determine the size of my array in C?

      • 我该如何确定C里面数组的大小?
    • That is, the number of elements the array can hold?
      • 即数组里面能容纳多少个元素?
  • 22 Answers:
    • Mark Harrison - 1394 people think it useful:

      • Executive summary:

        • 摘要:
        • int a[17];
        • size_t n = sizeof(a)/sizeof(a[0]);
      • Full answer:
        • 完整答案:
      • To determine the size of your array in bytes, you can use the sizeof operator:
        • 数组所占空间的大小(字节),可以通过sizeof操作来确定。
        • int a[17];
        • size_t n = sizeof(a)/sizeof(a[0]);
      • On my computer, ints are 4 bytes long, so n is 68.
        • 在我的计算机中,int占4个字节,所以n等于68。
      • To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:
        • 数组能容纳元素的个数,可以通过数组总大小除以数组元素大小来确定。数组元素的大小可以用它的类型大小表示,像这样:
        • int a[17];
        • size_t n = sizeof(a) / sizeof(int);
      • and get the proper answer (68 / 4 = 17), but if the type of a changed you would have a nasty bug if you forgot to change the sizeof(int) as well.
        • 就可以得到正确的答案(68 / 4 = 17),但如果类型改变且又忘记改变sizeof(int)里的int,那就会出现个讨厌的bug。
      • So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.
        • 所以最好是将sizeof(a[0])作为除数,或者是sizeof(*a),即数组第一个元素的大小。
        • int a[17];
        • size_t n = sizeof(a) / sizeof(a[0]);
      • Another advantage is that you can now easily parameterize the array name in a macro and get:
        • 另一个挺方便的方法,是定义一个宏,并将数组名参数化,像这样:
        • #define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
        • int a[17];
        • size_t n = NELEMS(a);
    • Elideb - 883 people think it useful:

      • The sizeof way is the right way iff you are dealing with arrays not received as parameters. An array sent as a parameter to a function is treated as a pointer, so sizeof will return the pointer's size, instead of the array's.

        • 在处理不是作为函数参数的数组时,sizeof的方式的确没错。数组作为函数的参数时会被视为指针,所以sizeof将会返回指针的大小,而不是数组的大小。
      • Thus, inside functions this method does not work. Instead, always pass an additional parameter size_t size indicating the number of elements in the array.
        • 因此,这个方法在函数内部没有效果。而为了获知数组的大小,最好再加一个size_t size作为函数的参数。
      • Test:
        • 例如下面的代码测试中所示,
        • 对于作为参数的数组指针,它返回的是Int指针的大小,
        • 而在函数外部对数组求大小,返回的是整个数组占据的大小,
        • 在译者的电脑(Windows 64位)中,int元素的大小是4,而int指针的大小是8,
        • 即便不是作为参数,而是新定义一个指针指向数组,亦是如此,
        • 这也解释了为什么答主的64位Linux显示Length of parameter等于2而不是1,
        • 因为8 / 4 = 2,
        • 这个问题让译者在LeetCode上纠结了一会:
        • #include <stdio.h>
        • #include <stdlib.h>
        • void printSizeOf(int intArray[]);
        • void printLength(int intArray[]);
        • int main(int argc, char* argv[])
        • {
        • int array[] = { 0, 1, 2, 3, 4, 5, 6 };
        • printf("sizeof of array: %d\n", (int) sizeof(array));
        • printSizeOf(array);
        • printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
        • printLength(array);
        • }
        • void printSizeOf(int intArray[])
        • {
        • printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
        • }
        • void printLength(int intArray[])
        • {
        • printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
        • }
      • Output (in a 64-bit Linux OS):
        • 在64位Linux系统中的输出:
        • sizeof of array: 28
        • sizeof of parameter: 8
        • Length of array: 7
        • Length of parameter: 2
      • Output (in a 32-bit windows OS):
        • 在32位Linux系统中的输出:
        • sizeof of array: 28
        • sizeof of parameter: 4
        • Length of array: 7
        • Length of parameter: 1
    • Magnus Hoff- 144 people think it useful:

      • It is worth noting that sizeof doesn't help when dealing with an array value that has decayed to a pointer: even though it points to the start of an array, to the compiler it is the same as a pointer to a single element of that array. A pointer does not "remember" anything else about the array that was used to initialize it.

        • 值得一提的是,sizeof在处理指向数组的指针时并没有效果,哪怕它指向的是数组的首位,因为编译器把数组中的单个元素当做指针来对待。因为一个指针并不会“记得”任何关于它被初始化成数组的事。
        • int a[10];
        • int* p = a;
        • assert(sizeof(a) / sizeof(a[0]) == 10);
        • assert(sizeof(p) == sizeof(int*));
        • assert(sizeof(*p) == sizeof(int));
    • unwind - 51 people think it useful:
      • The sizeof "trick" is the best way I know, with one small but (to me, this being a major pet peeve) important change in the use of parenthesis.

        • sizeof是我知道最好的技巧,不过在括号的使用上,有一个很小但很重要的改变(对我来说,这个是最令我烦恼的)。
      • As the Wikipedia entry makes clear, C's sizeof is not a function; it's an operator. Thus, it does not require parenthesis around its argument, unless the argument is a type name. This is easy to remember, since it makes the argument look like a cast expression, which also uses parenthesis.
        • 维基百科的条目中解释的很清楚,C的sizeof不是一个函数,而是一个运算符。因此,并不需要在参数旁边加括号,除非这个参数是个类型名称。这很容易记下来,因为它使得参数看起来像个强制转换表达式,也使用括号的那种。
      • So: If you have the following:
        • 所以:如果你这么定义数组:
        • int myArray[10];
      • You can find the number of elements with code like this:
        • 你可以这样来求它的元素个数:
        • size_t n = sizeof myArray / sizeof *myArray;
      • That, to me, reads a lot easier than the alternative with parenthesis. I also favor use of the asterisk in the right-hand part of the division, since it's more concise than indexing.
        • 这对我来说,比带括号的形式好理解多了。我也赞成在除法的右边使用星号,因为这比用下标要简洁。
      • Of course, this is all compile-time too, so there's no need to worry about the division affecting the performance of the program. So use this form wherever you can.
        • 当然,这都是编译时的,所以不用担心除法会影响程序的性能。所以尽可能的用这种形式。
      • It is always best to use sizeof on an actual object when you have one, rather than on a type, since then you don't need to worry about making an error and stating the wrong type.
        • 最好将sizeof用在实际对象里,而不是类型,因为这样不用担心造成bug或写成错误的类型。
      • For instance, say you have a function that outputs some data as a stream of bytes, for instance across a network. Let's call the function send(), and make it take as arguments a pointer to the object to send, and the number of bytes in the object. So, the prototype becomes:
        • 例如,假设你有一个函数,通过输出一些字节流数据的函数。我们调用send(),并且将参数设为一个指向待发送对象的指针,以及这个对象占据的字节数。所以,原型变为:
        • void send(const void *object, size_t size);
      • And then you need to send an integer, so you code it up like this:
        • 需要发送一个整型时,可以这样做:
        • int foo = 4711;
        • send(&foo, sizeof (int));
      • Now, you've introduced a subtle way of shooting yourself in the foot, by specifying the type of foo in two places. If one changes but the other doesn't, the code breaks. Thus, always do it like this:
        • 现在,你已经知道了一个能搬起石头砸自己的脚的办法,即在两个地方制定foo的类型。如果只有一个改变而另一个没有,代码会出错。因此,习惯这么做:
        • send(&foo, sizeof foo);
      • Now you're protected. Sure, you duplicate the name of the variable, but that has a high probability of breaking in a way the compiler can detect, if you change it.
        • 现在没问题了。没错,你可以复制变量名,但如果你改变了它,很可能会被编译器检测出错。

stackoverflow热门问题(二)- 如何确定C的数组的大小相关推荐

  1. Stackoverflow热门问题(二十二)-如何在Windows cmd中得到程序返回值?

    文章首发及后续更新:https://mwhls.top/2873.html 新的更新内容请到mwhls.top查看. 无图/无目录/格式错误/更多相关请到上方的文章首发页面查看. stackoverf ...

  2. Stackoverflow热门问题(七)-为什么printf在遇到新行时才清空缓冲区,而不是调用后立即清空?

    文章首发及后续更新:https://mwhls.top/2333.html 新的更新内容请到mwhls.top查看. 无图/无目录/格式错误/更多相关请到上方的文章首发页面查看. stackoverf ...

  3. HDU2642(二维的树状数组)

    二维的树状数组,我记得是模版!^ _ ^ 题意很清楚:就是这部分的原理:sum(x1,y1)+sum(x2-1,y2-1)-sum(x1,y2-1)-sum(x2-1,y1);其实可以和概率论中的一个 ...

  4. java 3维_java 二维/三维/多维数组

    如图,声明一个数组,引用存在栈中,new出来的对象存在堆中. 我把多维数组理解为数组中嵌套另一个数组. 下方代码为三维数组,如果是动态赋值,只需要声明多维数组的大小(new int[3][][]),需 ...

  5. 【C 语言】二级指针作为输入 ( 二维数组 | 二维数组内存大小计算 | 指针跳转步长问题 )

    文章目录 一.二维数组内存大小计算 二.二维数组内存大小意义 一.二维数组内存大小计算 给定一个二维数组 : 该 二维数组 中有 444 个 一维数组 , 每个一维数组有 101010 个 char ...

  6. 间接通过new 来申请一个二维的堆内存数组

    我们知道无法直接通过new 来申请一个二维的堆内存数组,于是有人想出了这样一个办法:创建一个一维堆内存指针数组,即每个数组元素是一个指针,然后用new 给各个指针分配一个一维的堆内存数组,那么最后表示 ...

  7. 堆化 二叉堆一般用数组来表示。typedef struct _minHeapNodetypedef struct _otherInfo-icoding-C-数据结构

    堆化 二叉堆一般用数组来表示.例如,根节点在数组中的位置是0,第n个位置的子节点分别在2n+1和 2n+2.  因此,第0个位置的子节点在1和2,1的子节点在3和4.以此类推.这种存储方式便于寻找父节 ...

  8. 堆元素插入 二叉堆一般用数组来表示。typedef struct _otherInfo{ int i; int j;}OtherInfo;-icoding-C-数据结构

    堆元素插入 二叉堆一般用数组来表示.例如,根节点在数组中的位置是0,第n个位置的子节点分别在2n+1和 2n+2.  因此,第0个位置的子节点在1和2,1的子节点在3和4.以此类推.这种存储方式便于寻 ...

  9. 堆初始化-二叉堆一般用数组来表示。例如,根节点在数组中的位置是0,第n个位置的子节点分别在2n+1和 2n+2-icoding-void init_min_heap(PMinHeap pq, int

    堆初始化 二叉堆一般用数组来表示.例如,根节点在数组中的位置是0,第n个位置的子节点分别在2n+1和 2n+2.  因此,第0个位置的子节点在1和2,1的子节点在3和4.以此类推.这种存储方式便于寻找 ...

最新文章

  1. mysql 开启慢查询命令【转】
  2. 文巾解题 620. 有趣的电影
  3. 服务器怎么查看数据库文件,怎么查看服务器上的数据库文件
  4. 基于不同STM32库函数的代码性能对比
  5. 1034 Head of a Gang (30 分) One way that the police finds the head of a gang is to check people‘s pho
  6. 小皮面板有php环境吗,体验phpStudy小皮面板创建LAMP/LNMP系统和建站图文
  7. JavaScript 时间戳(互相转换)(自定义格式)- 案例篇
  8. 【java】Java运行时动态生成类几种方式
  9. 智慧停车场管理系统、停车位、停车费、停车场系统、寻车、抬杆、入位车、出位车、车流量统计、停车、收费、缴费、预警管理、业务统计、报警统计、运维管理、报警系统、异常页面、数据配置、智慧停车原型、停车场
  10. 电商知识图谱的构建及搜索推荐场景下的应用实践
  11. 400 道前端面试题!阿里、头条、网易等 19 家大厂面经全公开!
  12. ABP架构学习系列二:ABP中配置的注册和初始化
  13. 自动驾驶_感知_目标检测(激光雷达)
  14. pb模型文件与.pbtxt配置不匹配导致OpenCV调用dnn模块出错(Mask R-CNN为例)
  15. python教程39-做个淘宝双十一满减攻略
  16. 修改Office文件的默认打开方式(含C#代码)
  17. 最新版继续教育学习软件下载地址
  18. SpringBoot Tomcat 配置https 且443端口也是https(若依为例对接微信小程序的https,小程序也可以访问)
  19. 用好WinXP自带的虚拟光驱
  20. 如何做一个python小程序?

热门文章

  1. HashMap与ConcurrentHashMap面试要点
  2. mysql out of range,mysql保存数据提示:Out of range value for column错误
  3. js简单交互动画,运动吧
  4. 太赞了!图解SQL基础知识,菜鸟也能看懂的SQL文章!
  5. 未来的计算机小报,未来科技生活手抄报图片实用美观
  6. docker创建CentOS云主机(docker实践)
  7. 第2章 IoC的基本概念
  8. 谷歌html弹出ie页面,HTML用JS识别浏览器,IE内核则调用谷歌打开指定链接
  9. OSPF多实例路由防环检测功能介绍
  10. [算法]Floyd-Warshall算法理解