雨天Zz 发表于 2020-8-31 23:45:12

指针变量

int w={{0,1},{2,4},{5,8}};
int (*p)=w;
p   p++,*(p+1)   w
谁能解释一下第二行的式子是什么意思,还有第三行的值分别是多少,怎么来的

sunrise085 发表于 2020-9-1 00:05:05

本帖最后由 sunrise085 于 2020-9-2 13:30 编辑

这是数组指针,指针指向一个长度为4的int类型一维数组
p是w的值,即4
p++是指针p自加1,p是数组指针,每次自加跳过的是数组的长度,也就是四个int类型的长度,所以p++是一维数组w的首地址,也就是2的地址
*(p+1)中的p+1和上一个的解释一样,有一点不一样,就是前面加上了*,那就不是以为数组的地址了,而是第二个一维数组的第一个元素的地址了,即w地址,也就是2的地址。这个和上一个值一样,但是意义不一样
w就是数组元素值啊,这里没有赋值,所以具体值不确定

关于数组指针,你可以看看我之前回答过的这个帖子

昨非 发表于 2020-9-1 00:05:51

我的理解是:
第二行:指针p指向数组w的同一位置,p和w本身的值是一个地址,二者同样指向这个二维数组
p即是w=4
p++应该是指针位置的下移(实测:仅第一维变动)
*(p+1)为下移后的地址(具体我也不懂,这部分不好理解啊)
最后w=0,是二维数组未被赋值的默认值
(如有错误,欢迎指正)



风过无痕1989 发表于 2020-9-1 00:41:22

本帖最后由 风过无痕1989 于 2020-9-1 01:23 编辑

       定义指向包含4个元素的一维数组的指针变量,并将二维数组的首地址赋给指针变量;

       要注意指针变量的类型,从"int(*p);"可以看到,p的类型不是int*型,而是int(*)型,p被定义为指向一维整型数组的指针变量,一维数组有4个元素,因此p的基类型是一维数组,其长度是32字节。例如:“*(p+2)+3"括号中的2是以p的基类型(一维整型数组)的长度为单位的,即p每加1,地址就增加32个字节(32位系统,4个元素,每个元素8个字节),而“*(p+2)+3"括号外的数字3,不是以p的基类型的长度为单位的。由于经过*(p+2)的运算,得到a,即&a,它已经转化为指向列元素的指针了,因此加3是以元素的长度为单位的,加3就是加(3×8)个字节。虽然p+2和*(p+2)具有相同的值,但由于它们所指向的对象的长度不同,因此(p+2)+3和*(p+2)+3的值就不相同了。

      题设赋值后,各数在数组中的位置:

      0    1    0    0
      2    4    0    0
      5    8    0    0

      p = 4                     // 指针指向第1行第1列,它的值就是4
      p++ = 1245008            // 指针p指向的是数组的首地址,p++是先运算再自加1(当然,各个系统的此值会有所不同的)
   *(p + 1) = 1245040       // p指向0行0列地址,首行有4个元素,每个元素占8个字节(32位系统),p+1便指向第2行0列,
                                           // 故:1245008 + 4 * 8 = 1245040 (当然此值也与系统有关)
   w = 0                  // 数组第2行第2列的值

风过无痕1989 发表于 2020-9-2 16:31:28

本帖最后由 风过无痕1989 于 2020-9-2 16:41 编辑

看来你还是没有理解指针数组,下面这个程序是我为了帮助自己理解、记忆而写的,每一条语句都是通过运行通过的,送给你吧:

// 输出二维数组的有关数据

#include <stdio.h>

int main()

{
    int a = {1,3,5,7,9,11,13,15,17,19,21,23};
    int *p,i,j;
    p = a;

    printf("%d\t%d\t%d\t",a,*a,p);                            //0行首地址和0行0列元素地址
    printf("//0行首地址和0行0列元素地址\n");
    printf("\n");
    printf("%d\t%d\t%d\t",a,*(a + 0),(p + 0));      //0行0列元素地址
    printf("//0行0列元素地址\n");
    printf("\n");
    printf("%d\t%d\t%d\t",&a,&a,&p);      //0行首地址和0行0列元素地址
    printf("//0行首地址和0行0列元素地址\n");
    printf("\n");

    printf("%d\t%d\t%d\t",a,a + 1,p + 4);             //1行0列元素地址和1行首地址, p + 4才是指向1行0列
    printf("//1行0列元素地址和1行首地址, p + 4才是指向1行0列\n");
    printf("\n");
    printf("%d\t%d\t\t",&a,*(a + 1) + 0);          //1行0列元素地址
    printf("//1行0列元素地址\n");
    printf("\n");

    printf("%d\t%d\t%d\t",a,*(a + 2),p + 8);      //2行0列元素地址, p + 8才是指向2行0列
    printf("//2行0列元素地址, p + 8才是指向2行0列\n");
    printf("\n");
    printf("%d\t%d\t\t",&a,a + 2);                         //2行首地址
    printf("//2行首地址\n");
    printf("\n");

    printf("小结:指针是按存贮方式指向,p + 1则指向0行1列,p + 2则指向0行2列\n");
    printf("因此,a在数组中的地址为:p + (i * m + j),(每行有 m 个元素)\n");

    for (p = a;p < a + 12;p++)                         // 使 p 依次指向下一个元素
    {
        if((p - a) % 4 == 0)                                    // p 移动4交换行
      {
          printf("\n");
      }
            printf("%4d",*p);                                       // 输出 p 指向的元素的值
    }
    printf("\n");
    printf("\n");
    p = a;
    scanf("%d,%d",&i,&j);                                               // 指定要输出的数组的行和列
    printf("a[%d,%d] = %d\n",i,j,*(*(a + i) + j));   // 输出指定元素的值
    printf("a[%d,%d] = %d\n",i,j,*(p + i * 4 + j));             // 输出指定元素的值

    return 0;
}
页: [1]
查看完整版本: 指针变量