c语言[]
本文我们将探讨一句诡异的代码。
一.问题
printf("%d", 2["hello world"]);
问: 输出结果?为什么?
这句代码对于初学C的同学来说,相信极其的诡异,2[“hello world”] ??这是个啥玩意??
二.[]操作符解析
要搞清楚这个问题,我们首先要弄清[]的含义。
首先,我们想一想,我们在哪里最常使用这个[]?没错,定义或使用数组的时候。
#include <stdio.h>
int main(
{
    int arr[5] = { 1, 2, 3, 4, 5 };
    int i = 0;
    for (i = 0; i<5; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}。
以这段代码为例,首先,定义数组时,我们使用了 [ ],表示的是,我们在内存上申请了5个整形即20个字节的连续空间,这里要注意,使用 [ ] 定义数组时,获得的空间一定是连续的!!而我们的数组名arr表示的是什么?表示的是首元素的地址。
总的来说,就是你用 int arr[5]; 定义数组时,编译器会给你开辟5个整形的连续空间,再这个空间的首元素地址作为数组名返回给你。所以我们说,C语言中,确定一个已知类型的数组需要两个元素,数组名(首元素地址),数组中元素的个数。
既然如此,我们便可以使用指针的基本写法来遍历数组。
#include <stdio.h>
int main(
{
    int arr[5] = { 1, 2, 3, 4, 5 };
    int i = 0;
    for (i = 0; i<5; i++) {
        printf("%d ", *(arr+i));
    }
    return 0;
}。
依然是上一段代码,这里我们使用*(arr + i)方式遍历数组,和arr[i]写法完全等价!
补充知识:指针+整数,表示以指针当前位置为起点,向后跳了整数位,上例中。arr为整形指针,arr+i表示以arr当前位置为起点向后跳了i个整形空间(i*4个字节)!
C语言认为,这样写太过啰嗦,于是有了 [ ] 操作符。
下面给出 [ ] 操作符的定义:。
定义数组时,向编译器申请一段连续的空间。
指针[i]表示以指针当前位置为起点,向后跳过i个该指针所指类型的大小的空间。
p[q] 等价于 *(p+q),若pq都不是指针则会报错!
根据第三条,我们可以写出这样的代码
#include <stdio.h>
int main(
{
    int arr[5] = { 1, 2, 3, 4, 5 };
    int i = 0;
    for (i = 0; i<5; i++) {
        printf("%d ", i[arr]);
    }
    return 0;
}。
i[arr] 等价于 *(i+arr) 等价于 *(arr + i) 等价于 arr[i]
如此,我们也就理解了上例中,为什么arr[5]会造成越界, 以arr为起点,向后跳过5个整形,此时arr指向了第六个整形空间,而我们定义的数组大小只有5个,自然就造成了越界!
这里我们一定要注意,[ ] 索引的必须要是一段连续的空间。想链表这种离散的存储结构,C语言中我们就一定不能使用 [ ] 来进行索引!
后话: C++可以对 [ ] 进行运算符重载,使我们可以用 [ ] 索引链表~。
三.问题解决
相信这时候,我们再看这句代码,就会容易许多。
c语言定义一个字符串
printf("%d", 2["hello world"]);
首先,我们要理解"hello world"是字符串,相当于字符数组,返回的是首元素即h的地址。
那么 2[“hello world”] 等价于 *(2 + “hello world”) 等价于 *(“hello world” + 2)
即将指向首元素h的指针再向后偏移两位,此时指针指向了第三个字符’l’。
再写好看些,这段代码就变成了。
char *s = "hello world";
printf("%d", s[2]);
所以这道题的答案便是,第三个字符l按%d输出,即l的ASCALL码值!
笔者水平有限,若有大佬指出错误与不足之处,笔者感激不尽!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。