11-数组与指针深入理解——题型理解
文章目录
- 11-数组与指针深入理解——题型理解
- 一、理解题1
- 二、理解题二
- 三、理解题三
- 四、理解题四
- 五、理解题五
- 六、理解题六
一、理解题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;
}
输出: