11-数组与指针深入理解——题型理解

11-数组与指针深入理解——题型理解

一、理解题1

#include <stdio.h>

int main(void)
{
 int (*p)[5] = NULL; // 定义一个指向 拥有5个整型数据的数组
 int arr[5] = {1,2,4,5,7};
 p = &arr; //指向arr数组的首地址(整个数组的首地址)

 printf("arr    = %p\n",arr );    
 printf("&arr   = %p\n",&arr );    
 printf("p      = %p\n",p);        
 printf("*p     = %p\n",*p );      
 printf("p+1    = %p\n",p+1 );    
 printf("(*p)+1 = %p\n",(*p)+1);  
 printf("(**p = %p\n",**p);  


 int a;//a是一个随机数
 printf("%p\n%p\n",a,&a );
 
 return 0;
}

输出:
在这里插入图片描述

二、理解题二

#include <stdio.h>

int main(void)
{

    int a[5] = {1,2,3,4,5};
    int b[3][4] = { {250,2,3,4}, {5,6,7,8}, {9,10,11,12}};

    printf("&a: %p\n",&a);  //数组的首地址     
    printf("&a+1:   %p\n",&a+1);     //数组的地址+1 加一整个数组的大小 这里是加20B
    printf("a:  %p\n",a); //首元素首地址           
    printf("a+1:    %p\n",a+1);  //第二个元素的地址

    printf("\n");
    printf("&b: %p\n",&b);  //数组的首地址     
    printf("&b+1:   %p\n",&b+1);//数组的地址+1 加整个二维数组的大小     
    printf("\n");
    printf("b:  %p\n",b); //二维数组中第一个元素的地址b[0][0]的地址 但是其实表示的是第一个元素(250,2,3,4)的地址    
    printf("b+1:    %p\n",b+1);//由上面的b的解析可知,这里加一应该是加一个元素(250,2,3,4)的地址   ,所以是{5,6,7,8}的首地址
    printf("\n");
    printf("*b: %p\n",*b);  //因为b指的是(250,2,3,4)的地址,所以*b指的是250的地址   
    printf("*b+1:   %p\n",*b+1);  //由上面的解析可知,*b+1 应该是增加一个“250 ”类型的地址,也就是增加一个整型的地址   
    printf("\n");
    printf("**b:    %d\n",**b); // *b 是 250的地址,**b则是250的值  
    printf("**b+1:  %d\n",**b+1); //**b是数值250,然后在这个值上+1 ,所以为2 与原数组第二个元素无关  


    printf("**(b+1):%d\n",**(b+2)); // b+2是增加两个元素的地址,也就是{9,10,11,12}的地址,*(b+2)是这9的地址,**()就是取出这个9 的值 

    printf("*(*(b+2)+2):%d\n",*(*(b+2)+2));  //b+2是{9,10,11,12}的地址,*(b+2)是9的地址,*(b+2)+2 是在9的地址的基础上加两个int型的地址也就是11的地址,然后*()就是取出11的值


    // 使用指针来访问二维数组的每一个元素
    for (size_t i = 0; i < 12; i++)
    {
        printf("%d\t" ,*((*b)+i) );
    }
    
    // 使用数组来访问二维数组
    for (size_t i = 0; i < 3 ; i++)
    {
        for (size_t j = 0; j < 4; j++)
        {
            printf("b[%d][%d]:%d\t" , i , j , b[i][j] );
        }
        
    }
    

    // *((*b)+i)

    return 0;
}

输出:
在这里插入图片描述

三、理解题三

#include <stdio.h>

int main(void)
{
    int arr[] = { 1, 3, 5, 7, 9};
    int i, *p = arr, len = sizeof(arr) / sizeof(int);


    for(i=0; i<len; i++)
    {
        //   * 和 ++ 得优先级是同级的 , 又因为当前这一级的结合性是从右往左 , 因此先 p++  , 但是是后缀所以先运算后++
        printf("%d\n", *p++ );   // 先运算得到 1  , 然后再地址+1 
        printf("%d\n", (*p)++ );  // 先得到p得内容  3 , 然后再对3进行自加
        for (size_t j = 0; j < len ; j++)
        {
            printf("arr[%d]:%d\t" , j , arr[j]);
        } 
        printf("\n");

    }
    printf("\n");
 

    


    return 0;
}

输出
在这里插入图片描述

四、理解题四


#include <stdio.h>

int main(void)
{
    int a = 1, b = 2, c = 3;
    int *arr[3] = {&a, &b, &c};//定义一个名字为arr的数组,数组中存放的是int 型指针,--> 整型指针数组
    int **parr = arr; // 第一部分 *p , 第二部分 int * 说明类型   为指针类型   +1 则+1个指针类型 8字节(64)

    //            arr[0]  --> &a   *&a --> a 
    printf("%d, %d, %d\n", *arr[0], *arr[1], *arr[2]);
    printf("%d, %d, %d\n", **(parr+0), **(parr+1), **(parr+2));
    return 0;
}

五、理解题五

#include <stdio.h>

int main(void)
{
    char *lines[5] =       //字符指针数组--> 创建一个名字为lines的数组,用来存放char * 指针
    {
  "COSC1283/1984",
  "Programming",
  "Techniques",
  "is",
  "great fun"
    };
 
    char *str1 = lines[1];  //   用来存放数组第一个元素的首元素的首地址    --》Programming
    char *str2 = *(lines + 3); //==>*lines[3]  输出 is
    char c1    = *(*(lines + 4) + 6);  //*(lines + 4)-->"great fun"的地址 +6 就是 字符 f 的地址 再取值
    char c2    = (*lines + 5)[5]; //*lines  --> "COSC1283/1984"中的C的地址,+5 得到2的地址, [5]--》以2为基础再往后+5个单位并取值为9
 
    char c3    = *lines[0] + 2;//先lines[0]得到C的地址,*则取值为C,+ 2 --》 C+ 2 = E
 
    printf("str1 = %s\n", str1);   
    printf("str2 = %s\n", str2);   
    printf("c1   = %c\n", c1);     
    printf("c2   = %c\n", c2);    
    printf("c3   = %c\n", c3);    
 
    return 0;
}

在这里插入图片描述

六、理解题六

#include <stdio.h>

int main(void)
{
 int i;
 int num;
 int (*p)[5] = NULL;  //数组指针   
 int arr[5] =  {5,2,4,5,7};
 p = &arr;
 
 printf("=====================================\n");
 num = sizeof(arr)/sizeof(arr[0]);
 for(i=0;i<num;i++)
 {
  printf("*p[%d] = %d\n",i,*p[i]);//根据优先级应该是先p[i]然后再取值。P是一个数组指针,它的类型是数组,+1是增加一个数组,所以输出只有第一个是正常的,后面的都越界了。
 }
 printf("=====================================\n");
  for(i=0;i<num;i++)
 {
  printf("*(p+%d) = %p\n",i,*(p+i));  //打印👆的地址,同理p为一个数组指针,+i 是增加一个数组的大小也就是五个整型,20个字节
 } 
 printf("=====================================\n");
 
 for(i=0;i<num;i++)
 {
  printf("p[%d] = %p\n",i,p[i]); // == *(p+i)  和前面的一样  
 }
 printf("=====================================\n");
 
 for(i=0;i<num;i++)
 {
  printf("(*p)[%d] = %d\n",i,(*p)[i]); //正确输出,先*p 得到首元素地址,首元素首地址[i],以首元素的地址为基准值进行单位的增加
 }
 
 return 0;
}

输出:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写的什么石山代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值