被初中生 C 语言考住了,尴了个尬

2022-08-28 11:32:15 +08:00
 52coder

周末来老婆老家,她亲戚有个小孩读初中,有个兴趣班学的 C 语言,得知我是从事软件开发 5 6 年的“高手”,饭后问了我一道编程题,我三俩下就告诉他怎么 怎么写,结果提交的时候始终显示有问题,一排查发现这里有坑,我手写一个 demo (可能编译不过哈)请教各位如下程序输出是什么?

#include <stdio.h>
int main()
{
    int arr[10] = {-1};
    //打印 arr 全部内容
    for(int i = 0;i < 10;i++)
    printf("%d",arr[i]);
    
    return 0;
}

我之前一直以为会全部输出-1 ,结果在 gcc 11.2.0 的环境下,输出确实一个-1 ,然后全是 0.有没有踩过这个坑的朋友?

10181 次点击
所在节点    程序员
83 条回复
kfakeman
2022-08-28 12:24:59 +08:00
@yhxx js 主要是让少考虑内存方面的问题吧
ffire
2022-08-28 12:25:47 +08:00
@52coder 另外换个角度,{ 0 }也是初始化第一个为 0 ,后面没指定都是 0 ,刚好达成了所有为 0 的效果。这和{ 1 }第一个为 1 ,后面都 0 的逻辑其实是统一的。
hello2090
2022-08-28 12:27:20 +08:00
@52coder 我忘了那些情况下会默认初始化为 0 了,你后面 9 个为 0 第一个想到的肯定是被默认初始化了啊,怎么会想成一个 10 元素数组只要提供 1 个值所有元素都能被赋成这个值呢?我无法理解
SunBK201
2022-08-28 12:30:26 +08:00
@hello2090 可能是因为这个:

int s[5]={0};
00EA17BE mov dword ptr [ebp-18h],0
00EA17C5 xor eax,eax
00EA17C7 mov dword ptr [ebp-14h],eax
00EA17CA mov dword ptr [ebp-10h],eax
00EA17CD mov dword ptr [ebp-0Ch],eax
00EA17D0 mov dword ptr [ebp-8],eax
yanqiyu
2022-08-28 12:34:57 +08:00
@ailer 后面一定是 0, 等同于静态初始化

毕竟一般初始化成 0 我会写成 int name[N] = {};或者 int name[N]{};
就是利用这个特性偷工减料
jdhao
2022-08-28 12:36:10 +08:00
yanqiyu
2022-08-28 12:36:35 +08:00
@yanqiyu 才注意到题目是 C, 空 list 是 C++特性。但是印象中 C 准备在 23 引入?
msg7086
2022-08-28 12:42:27 +08:00
没踩过,一直记得是初始化成 0 的。这里第一个元素是-1 ,剩下的元素没有指定值,所以初始化成 0 。

其实想想就知道不可能全部是-1 了。
你说 int arr[10] = {-1, -2};,后面的到底是-1 还是-2 还是-3 ?
honamx
2022-08-28 12:46:52 +08:00
没踩过,很简单很基础的题,只是楼主 C 基础不好。
retrace
2022-08-28 12:49:45 +08:00
楼主你还是改行吧
cmdOptionKana
2022-08-28 13:02:10 +08:00
C 语言是比较底层的语言,给程序员很大的自由度,很多行为不能靠猜的。楼主实在是太久没写 C 了吧。
AllenHua
2022-08-28 13:06:07 +08:00
啊这,arr 数组,下标 0 主动赋值了 -1 ,后面的 9 个坑默认初始化成 0 啊,我记得 C 语言前几节课程就会讲到这点。
TGl2aWQgZGUgZGll
2022-08-28 13:17:05 +08:00
小盆友心想:就这还高手?呸~
TGl2aWQgZGUgZGll
2022-08-28 13:17:48 +08:00
@zooo #12 后面的 0 都是默认的,不是因为第一个是 0 ,后面都赋值 0
zooo
2022-08-28 13:18:47 +08:00
好像看过一个 C++的规范,尽量不要依赖默认初始化...(不知道是不是有这条)

所以还是 memset 下
zooo
2022-08-28 13:19:57 +08:00
@TGl2aWQgZGUgZGll
int w[3] = {0}
也就是上面这种写法其实没必要?
wunonglin
2022-08-28 13:20:37 +08:00
不是。。。按我 js 、go 的思维,初始化了 10 个长度的数组,只给了一个值,那其余的应该都是默认值才对不是么,我觉得没问题
apake
2022-08-28 14:32:15 +08:00
很久没写了吧. 默认为 0, 这是 C 的基础
zhicheng
2022-08-28 14:49:28 +08:00
“c 指定非 0 值还要 memset(arr,-1,sizeof(int)*10)大概这种。”
不会写 C 说不会就好,没必要假装。
microxiaoxiao
2022-08-28 14:54:00 +08:00
这种叫部分初始化。部分初始化确保了立即给他分配一段内存。它是按照数组下标顺序初始化,没有明确赋予值得会给出 0 值,如果理解了这一条其实就能明白它仅仅初始化了数组 0 。再举个显眼的例子,int num[3] = { 5, 7 };这种你就能明白了。按照顺序初始化 0 ,1 下标得值,得到 num[0] = 5, num[1] = 7 ,其余得赋值为 0 , 如果想跳过 1 初始化也是 OK 的, int num[3] = { [0]=5,[2]= 7 }。 这样应该就不会困惑了。至于为啥要一般写法 memset ,我之前有个帖子讨论过。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/875942

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX