鱼C论坛

 找回密码
 立即注册
查看: 2043|回复: 7

C语言数组指针问题。

[复制链接]
发表于 2015-2-5 14:47:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 NSE 于 2015-2-6 15:11 编辑
  1. #include <stdio.h>
  2. #define f "%d,%d\n"//宏
  3. int main()//主
  4. {
  5.         int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};//定义二维数组

  6.         printf(f,a,*a);//输出a的地址,输出a的地址

  7.         printf(f,a[0],*(a+0));//输出a的地址,输出a的地址

  8.         printf(f,&a[0],&a[0][0]);//取出a的地址,取出 a 行 列首地址

  9.         printf(f,a[1],a+1);//输出 a一行 0列地址,输出a一行 0列地址

  10.         printf(f,&a[1][0],*(a+1)+0);//输出a一行 0列地址,输出a1行0列地址

  11.         printf(f,a[2],*(a+2));//输出2行 0列地址,输出2行0列地址

  12.         printf(f,&a[2],a+2);//取 2行0列地址,取2行地址

  13.         printf(f,a[1][0],*(*(a+1)+0));//值为9,值为9

  14.         return 0;
  15. }
复制代码
我写的注释部分和 书本写的不一样 怎么去 运用指针到多维数组和数组上?
数组和多维数组在内存上的概念我理解 就是用指针表示 理解没透彻。

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-2-5 17:23:14 From FishC Mobile | 显示全部楼层
只要理解内存怎么存的就ok了,指针只是一种表示方法,不行就换一个方式来自: iPhone客户端
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2015-2-5 17:43:57 | 显示全部楼层
百日维新 发表于 2015-2-5 17:23
只要理解内存怎么存的就ok了,指针只是一种表示方法,不行就换一个方式

你说的好轻松。。。你来表示下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-5 19:26:12 | 显示全部楼层
NSE 发表于 2015-2-5 17:43
你说的好轻松。。。你来表示下

你知道的,我还是菜鸟....


内存模型

1,1375884
3,1375888
5,1375892
7,1375896
9,1375900
11,1375904
13,1375908
15,1375912
17,1375916
19,1375920
21,1375924
23,1375928

前面是数,后面是地址:我们看到了 地址之间相隔4个字节。因此内存地址是线性的,在内存中都当做一维数组。

int a[3][4]={ {1,3,5,7}, {9,11,13,15}, {17,19,21,23}}; //最好写成这样,增加可读性。

printf("%d %d \n",a[1][0],*(*(a+1)+0));

*(*(a+1)+0) : a是地址( int (*)[] 类型,指向二维数组第一维),a+1就是数组第一维   (a[0])+ 偏移地址1 —— > a[1]   (int (*)[]类型)

* (a+1)  *号 将 a+1的地址解引用变成 int* 类型的值  a[1][0]

*(int* 值 + 0)这个值在偏移0,之后解引用,变成一个int值。

个人理解,请勿轻信,我也是没理解透,总是找不到逻辑,各种书上写的不知哪个对

导师,求正确答案 @仰望天上的光








想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-5 19:27:40 | 显示全部楼层
#include <stdio.h>

#define f "%d,%d\n"//宏

int main()//主

{

        int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};//定义二维数组

        for(int* p = a[0];p < a[0]+12;p++)
        {
            printf(f,*p,p);
        }

        return 0;

}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2015-2-5 19:33:16 From FishC Mobile | 显示全部楼层
NSE 发表于 1 小时前
引用:   百日维新 发表于 2015-2-5 17:23   
只要理解内存怎么存的就ok了,指针只是一种表示方法,不行就换一个方式  
你说的好轻松。。。你来表示下...

用数组代替,学计算机最忌讳就是钻牛角尖,太深太多你不可能学完的,工作需要什么就学什么来自: iPhone客户端
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-6 10:40:05 | 显示全部楼层
我们可以把
int a[3][4]理解为定义了一个"变量"它是一个数组,有3个元素,每个元素的类型为int [4];
干脆这样定义看的更清楚:
typedef int Vec[4];
Vec a[3];//等价于int a[3][4];
又,从形式上看, *(a+n)等价于a[n]
所以:
printf(f,a,*a);中,输出的数组a退化为数组a首元素的指针(类型为int(*)[4]即Vec*),*a等价于*(a+0)也就是a[0]
这是一个类型为Vec的数组,它退化为该数组手元素的指针(类型为Vec),这里输出的两个数值相同,但数据类型不同。

printf(f,a[0],*(a+0));这里*(a+0)同上面的*a,不解释


printf(f,&a[0],&a[0][0]);
这里,a[0]就是*(a+0),所以&a[0],就是&*(a+0),也就是 a+0,也就是a前面解释过。
&a[0][0]中,a[0][0]是  *(a[0]+0),&a[0][0]就是&*(a[0]+0),就是a[0]+0,也就是a[0],前面也解释过

printf(f,a[1],a+1);中
a[1]就是数组a 的第一个元素,前面定义了数组a为 Vec a[3];所以 &a[1] = &a[0] + sizeof(Vec),其中,sizeof(Vec)=sizeof(int) * 4。 前面说过,&a[1]的值和a[1]相同(类型不同),所以这个值自己可以算出来。

a+1等价于&(*a+1)也就是&a[1],这个值和a[1]相同(类型不同)

OK,剩下的自己推导吧。。。这里的思想精华是:不要管什么多维数组,统统看成  Type  a[n]; 取出元素后再看Type是什么类型。

评分

参与人数 1荣誉 +8 鱼币 +8 贡献 +5 收起 理由
拈花小仙 + 8 + 8 + 5 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2015-2-6 15:11:58 | 显示全部楼层
仰望天上的光 发表于 2015-2-6 10:40
我们可以把
int a[3][4]理解为定义了一个"变量"它是一个数组,有3个元素,每个元素的类型为int [4];
干脆 ...

谢啦。导师
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-21 00:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表