学c语言我犯的低级错误: 关于数组和字符串

103 阅读3分钟

12230bf7ec11ed00d75d316231565a8e.png

我第一次写了一个这样的代码,使用vs2022编译得到了输出-858993460

我理想中的情况是我定义了int数组1,2,3,4,(\0),arr[3]指代的是数组中下标为3的元素4,这犯了以下几个错误:

(1)"1234"是一个字符串,不是int类型数组

(2)即使定义的是char类型数组,格式应为

char arr[] = {'1','2','3','4'};( 不含\0) 或者 char arr[] = "1234";(自带\0)

但我并不知道,感到很疑惑,于是第二次又写了这样一个代码

ac36cfd115a394bbface636cee6eb388.png

得到了输出1

这一次,数组类型没有问题,但结果依然不是我想要的,我期望输出的结果为4*4=16

经过重新学习复盘,我发现了问题:

第一,char数组和字符串都是字符类型,区别在于字符串是一种特殊的char数组,它自带\0空字符,而char数组在不自主添加\0元素的时候不自带\0,这就导。致在用strlen函数求数组长度时,普通char数组为随机值,字符串才为非空字符的个数。

第二,int数组不是字符类型,没有"\0"、"strlen"这一说,"\0"是一个字符,而非一个整形,strlen是string length的缩写,跟int类型没有关系。

知道了错误之后,我又产生了疑惑,因为我两个代码虽然得到了意料之外的结果,但是都没有报错,经过分析,原因如下

第一段代码:vs2022编译器中,在不进行强制类型转换的情况下,如果类型不匹配,编译器会自动转换 例如:

int a = 3.14;

3.14 默认为double类型,而非整型,这时编译器将会取整,将3赋值给a

同样,在第一段代码中,虽然我写错了,vs还是尝试把1234理解为一个整形并放到整型数组中,这时候的arr只有一个整形元素,也就是arr[0],也就是1234,这时我访问的arr[3]是未分配的内存,编译器将自动输出随机值。(至于为啥是这个数是vs调试模式认定的,对应十六进制0xCCCCCCCC)

第二段代码 (有点高深,引用deepseek解释):

  1. strlen() 函数是用于字符串的,它期望接收一个以 \0 结尾的字符数组(字符串)。
  2. 你传递给它的是一个整型数组,strlen() 会错误地将整数值解释为字符。
  3. 在大多数系统中,整数 1 的低字节是 1,高字节是 0(小端序)。strlen() 遇到第一个零字节(整数 1 的第二个字节)就认为字符串结束了。
  4. 因此,strlen(arr) 返回 1,这就是你看到输出为 1 的原因。

同时还有一个概念要区分,我在写的时候有些模糊不清:

1.赋值时 arr[x] x是占用内存,对应sizeof 如果为字符串包括自带的\0在内

2.访问时 arr[y] y是元素下标,\0没有下标不包含在内,并且下标是从0开始数的

(刚开始学,第一次写这种> <可能有地方用语不专业,记录个人错误顺便做笔记哈哈哈哈)