关于C语言malloc数组、指针操作及数组下标语法的困惑咨询
嘿,我完全懂你现在的困惑——C语言里的指针和数组组合起来确实容易让人脑袋打转转,尤其是刚接触动态分配的时候!咱们一步步把你遇到的几个问题拆开说清楚,保证你能捋明白。
拆解你遇到的C指针&数组困惑
1. 为什么*p+i打印出递增的数字,而p[i]却正确?
这核心是运算符优先级在搞鬼:
*(解引用)和+(加法)的优先级里,*更高,所以*p+i会被编译器解析成(*p) + i——也就是先取出p指向的第一个元素的值(55),再加上循环变量i,结果自然就是55、56、57...- 而
p[i]是C语言给咱们的语法糖,它等价于*(p+i)!编译器看到下标操作时,会自动把它转换成「指针偏移i个单位后解引用」的逻辑。p+i是从起始地址往后偏移i个int的地址,再用*解引用就拿到了第i个元素的值,这正是你想要的结果。
2. 为什么*p++能正常打印所有值?
这里要讲后缀++的优先级和特性:
- 后缀
++的优先级比*更高,所以*p++等价于*(p++)。 - 后缀
++的特点是先返回变量当前的值,再让变量自增。第一次执行时,先返回p当前指向的地址(第一个元素的地址),解引用后拿到55;然后p自增,指向第二个元素的地址。第二次循环时,重复这个逻辑拿到66,以此类推,所以能正确打印所有输入的数值。
3. 为什么scanf("%d", p[i])会报语法错误?
scanf的第二个参数要求传入的是存储输入值的地址(类型为int*),而p[i]是解引用后的结果——它是一个int类型的具体数值,不是地址,编译器自然会报错。
你应该用&p[i](取第i个元素的地址),或者p+i(和&p[i]完全等价,因为p是int*指针,偏移i个单位就是第i个元素的地址),这和你之前写对的scanf("%d", p+i)是同一个逻辑。
再帮你巩固几个核心概念
为了避免再绕晕,咱们把这些指针操作的本质再理一遍:
p:指针变量,存储的是malloc分配的内存的起始地址。*p:解引用操作,拿到p指向的地址里存储的具体值。p+i:指针偏移操作,得到从起始地址往后第i个int的地址(因为p是int*,所以实际偏移的字节数是i * sizeof(int))。*(p+i):解引用偏移后的地址,拿到第i个元素的值,p[i]就是它的语法糖,两者在编译器眼里完全一样。
内容的提问来源于stack exchange,提问作者C0DEV3IL
相关产品推荐
相关产品推荐

