#include <stdio.h> const int MAX = 3; int main () { int var[] = {10, 100, 200}; int i, *ptr; /* 指针中的数组地址 */ ptr = var; for ( i = 0; i < MAX; i++) { printf("存储地址: var[%d] = %x\n", i, ptr ); printf("存储值: var[%d] = %d\n", i, *ptr ); /* 移动到下一个位置 */ ptr++; } return 0; }
其中的 ptr = var; 这里是把数组 var 的第一个值得地址赋值给了 ptr 指针吗? 那可不可以这样写 ptr = &var[0];
刚学。可能问的问题弱智了点,还是期望有人解惑..
1 am241 2017-01-30 20:06:06 +08:00 可以这样写,不过没必要 |
2 stevezjb 2017-01-30 20:07:56 +08:00 var=&var[0] |
![]() | 3 liyvhg 2017-01-30 20:11:11 +08:00 via Android ![]() 这两种写法是等价的 |
![]() | 4 LGA1150 2017-01-30 20:17:08 +08:00 via Android 一个引用&,一个解引用[],正好抵消 |
![]() | 5 firebroo 2017-01-30 20:22:38 +08:00 via Android 可以的。 |
6 cio OP 谢谢!理解了。我再去好好看看书.. |
![]() | 7 Lonely 2017-01-30 22:20:19 +08:00 via iPhone 理一下顺序就是&(var[0]) |
![]() | 8 sfqtsh 2017-01-30 22:25:18 +08:00 via Android var 的类型是 int [3],是个数组类型, ptr 类型是 int*,是个指针类型,前者可隐含向后者转换,指向其首地址。 var[0]类型是 int ,所以&var[0]类型就是 int*。 |
9 owt5008137 2017-01-30 22:25:28 +08:00 via Android 可以,一样的 |
![]() | 10 NvSylvanas 2017-01-30 22:50:32 +08:00 可以 |
11 lzhCoooder 2017-01-30 23:18:02 +08:00 数组名代表数组首地址,这应该是很重要的一个概念,记住它就不会有疑惑了 |
12 klesh 2017-01-31 00:16:37 +08:00 via Android 看的什么书?合格的入门级会直接给多第二种写法,并说明是等效的。 |
![]() | 13 msg7086 2017-01-31 02:17:53 +08:00 a[b] 就是 *(a+b) 的语法糖。 &a[b] 自然就是 (a+b) 。 b 是 0 的情况下,&a[0] 就是 (a+0) 也就是 a 了。 |
![]() | 14 justyy 2017-01-31 02:21:02 +08:00 a[b] 可以写成 b[a] |
![]() | 15 424778940 2017-01-31 02:51:44 +08:00 数组的名字所指向的地址就是数组第一个元素的地址 所以你直接用名字和取第一个元素的地址 结果应该是一样的 |
![]() | 16 ryd994 2017-01-31 08:57:11 +08:00 via Android 学深点你就知道 a[i]==*(a+i) 所以可以用这种办法直接偏移数组 |
![]() | 17 ryd994 2017-01-31 08:59:28 +08:00 via Android ![]() 推荐你再零长度数组 https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html 会感觉打开了新世界的大门 然后乱飞指针无法自拔,直到写出自己都看不懂的代码为止 我就是这么过来的 |
![]() | 19 zhujinliang 2017-01-31 10:04:31 +08:00 via iPhone 我觉得&a[n]写法更好,因为 a 的类型不确定,用数组的形式编译器会自动决定偏移多少 自己处理指针除非有特殊用途 |
![]() | 22 ryd994 2017-01-31 12:59:55 +08:00 |
23 introom 2017-01-31 14:42:54 +08:00 via Android @ryd994 之前楼上那位的意思应该是说,比如 int arr = {1,2,3} 那么, arr[1]和 1[arr]一个意思。 你的问句是,如果 a,b 不是一个类型呢? 所以 a,b 是一个类型是什么意思? |
![]() | 24 crazyjin 2017-01-31 15:40:01 +08:00 楼主去看看《 csapp 》的前几章,再看看《 c 陷阱与缺陷》。你会理解 c 的指针的本质,并且见识一些极端复杂的用法。 |
25 snnn 2017-01-31 18:42:44 +08:00 |
27 mintist 2017-02-01 15:00:22 +08:00 ![]() C 语言中的 **指针** 由两部分构成:地址值和类型。 地址值就是数字,和汇编中是一样的。 而类型,在汇编里面是没有的,所以是给 C 语言的编译器看的,在编译期间, C 语言会根据你写的指针类型给它们分配所需要的空间。 (或者说是弱类型吧,不能说没有类型,而是只有简单的不同位数的整形,浮点型,而没有指针,数组,数组的数组之类的高阶的类型,因为汇编器是比较原始的,没有那么复杂的设计) 再回到题主的问题: “ ptr = var; 这里是把数组 var 的第一个值得地址赋值给了 ptr 指针吗? 那可不可以这样写 ptr = &var[0];” 这里有两个变量和类型: ptr ,它的类型是 int *,为指向整形的指针; var ,它的类型是 int [3],为有 3 个整形元素的数组。 var[0],它的类型是 int ,是*(var+0)的语法糖,所以自然也可以写成*(0+var),进一步的写成 0[var]。 而 & 表示取地址符的意思,所以 &var[0] 的类型是 int *。 所以,后两者只是地址值是相等的,其类型是不同的。 那么类型不同体现在什么地方呢?比如 sizeof(var) = 3*4 =12;而 sizeof(var) = 4 (假设为 32 位的机子) 当然,还有一些场景,两者会相互转换,比如函数传参数,数组会退化成指针,楼主用 “ C language array & pointer difference ”搜索下估计就能搜到不少 清楚了类型之后,可以看到,后者的写法是更加正确的,因为左右的类型都是 int *,而前者的写法左右两边类型是不同,有一个类型自动转化在里面,就是地址值过去了,类型给忽略掉了。 |
28 mintist 2017-02-01 15:02:25 +08:00 所以,一般个人在写的时候,会把 ptr = var;改成 ptr = (int*)var;,虽然必要性不大,但是这样写只是为了告诉自己,后面就用 int * 类型的指针去访问这段内存吧,的意思 |
![]() | 29 visionsmile 2017-02-02 20:31:02 +08:00 @424778940 @lzhCoooder 数组名不是指针,标准里面是这么写的: Here x is a 3 × 5 array of integers. When x appears in an expression, it is converted to a pointer to (the rst of three) ve-membered arrays of integers. In the expression x[i] which is equivalent to *(x+i), x is rst converted to a pointer as described; then x+i is converted to the type of x, which involves multiplying i by the length of the object to which the pointer points,namely ve integer objects. |
30 lzhCoooder 2017-02-03 10:41:42 +08:00 @visionsmile 数组名当然不是指针,我没说是指针呀...稍微写过一点就知道 sizeof 一个数组和一个指针结果是很不一样的,你搬出标准也只能证明数组名会被隐式转换成数组首地址,这我说的没错呀,一般用起来数组名就是代表首地址... |
![]() | 31 visionsmile 2017-02-03 12:43:22 +08:00 @lzhCoooder “你搬出标准也只能证明数组名会被隐式转换成数组首地址”,那不然还证明啥?“一般用起来数组名就是代表首地址...”,你这样说理解起来会有很大歧义....因为它并不“代表”首地址,只是在使用时会转换为指针。措辞还是要严谨一些啊。 |