这些 C 语言的题,各位不用电脑纯手写的话,能做到什么程度呢?

查看 420|回复 32
iOCZS   
@AFOX 的确如此
AFOX
OP
  
来自 ChatGPT 对第一题的解释:
1. **数组声明和初始化**:
```c
int a[5] = {1, 2, 3, 4, 5};
```
这行代码声明了一个包含 5 个整数的数组 `a`,并将其初始化为 1, 2, 3, 4, 5 。
2. **指针初始化**:
```c
int *p = &a + 1;
```
这一行代码比较复杂。我们逐步解析:
- `&a` 是数组 `a` 的地址。`&a` 的类型是 `int (*)[5]`,即指向一个包含 5 个整数的数组的指针。
- `&a + 1` 表示将指针 `&a` 向前移动一个单位,这里的单位是整个数组 `a` 的大小(即 5 个整数的大小)。因此,它指向的是数组 `a` 之后的内存位置。
- `&a + 1` 的类型仍然是 `int (*)[5]`。
- 将 `&a + 1` 赋值给 `int *p` 时发生了隐式转换。最终 `p` 指向的是紧跟在数组 `a` 之后的内存位置。
总结来说,`p` 指向的是数组 `a` 结束之后的那块内存位置。
为了更好地理解这一点,我们来看一下内存布局:
```
地址 值
0x1000 1 (a[0])
0x1004 2 (a[1])
0x1008 3 (a[2])
0x100C 4 (a[3])
0x1010 5 (a[4])
0x1014 ? (p 指向这里)
```
在这里,`p` 指向地址 `0x1014`,也就是在 `a[4]` 之后的内存位置。
### 访问 `p`
在这种情况下访问 `*p` 是未定义行为,因为它指向的是数组 `a` 结束之后的那块内存位置。
你是否需要更多关于指针运算的信息,或者对这个代码有其他具体的问题?
basncy   
关于第一题, 联想后面的 I2C 和 TCP, 表面上是指针, 实际是通过 offset 快速定位. 通信协议里经常用 offset 取特定信息 .https://zh.wikipedia.org/zh-cn/IPv4
但是 &a + 1 这种写法, vc++ 能过? 这么多年, linux 下从来没见过这种写法, 请 Linux 开发的面试官们手留情, 别误导青少年了.
https://ibb.co/K7Lr73v
AFOX
OP
  
@basncy
我很同意你的第一点,面试官应该是想考察通过 offset 快速定位的知识点,但是感觉题没出好 hh
第二点的话,我刚刚试了在 gcc 7.5 下还是可以编译通过,但是会报 warning 了。
yxd19   
@basncy
加个类型转换就行。
https://godbolt.org/z/f6jb1P661
也不用联想那么多。。联想到 C 里对多维数组的支持就理解了。
yxd19   
第一题关键在于想到 sizeof(a)是啥(是 5*sizeof(int))
basncy   
@yxd19 #24 (&a + 1);已经越界了, code review 过不了. 加个(int*)哄编译器吗?
ncisoft   
题目出得不错,公司的研发团队素质挺好的 ^-^
shijingshijing   
13 应该不会这么简单,要考虑是否启用 secure boot ,还有就是 x86 和 ARM 的启动还是有区别的。
w568w   
只说第一题哈,严格来说是不应该通过编译(或者说不鼓励写)的。
关键在于 (&a + 1)。指针的加法运算仅对「指向数组元素的指针」有定义,而 a 显然不是一个数组元素。所以 &a+1 的定义是依赖编译器实现的。
在连续的虚拟地址空间下,才能理想地认为 &a+1 代表 a 向后 5 个 sizeof(int) 字节的位置,然后再减 1 得到指向 a[4] 的指针。刻板地说,这题如果不加上这样那样的假设,那就是回答不了的。
您需要登录后才可以回帖 登录 | 立即注册

返回顶部