C语言 day9 | 我的日常分享

C语言 day9

指针

指针数组

存放指针变量的数组

案例1:

1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
int main(int argc,char *argv[]){
int a = 10,b = 20, c = 30;
int *arr[3] = {&a, &b, &c};
char *arr2[3];

printf("%d\n",*arr[1]);//20
printf("%d\n",sizeof(arr));//12
printf("%d\n",sizeof(arr2));//12
return 0;
}

分析:
第8、9行代码结果都为12的原因是,在32位的平台下,只要是指针都是4字节的,所以 3 * 4 = 12

案例2:

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
int main(int argc,char *argv[]){
char *arr[3] = {"hello","world","hahaha"};

printf("%d\n",sizeof(arr));//12
printf("%s\n",arr[0]);
printf("%s\n",arr[1]);
printf("%s\n",arr[2]);
return 0;
}

运行结果:
图片

分析:
"" 双引号取得是字符串的地址,所以char *arr[3]中的三个元素存的分别是"hello""world""hahaha"的起始地址,而打印字符串的时候的%s需要的也是字符串的首地址,然而char *arr[3]保存的就是字符串的地址.不然字符串"hello""world""hahaha"都超过了四字节,那char *arr[3]怎么可能存的下去。

拓展:打印出"world"中的'r'

1
2
3
4
5
6
7
#include<stdio.h>
int main(int argc,char *argv[]){
char *arr[3] = {"hello","world","abcdefg"};

printf("%c\n",*(arr[1]+2));
return 0;
}

运行结果:
图片

分析:
要打印字符'r',输出格式就是%c,他需要的就不是地址,我们需要对地址取 * ; 首先我们要找到字符'r'的地址,我们知道arr[1]储存的是字符串"world"的首地址,也就是字符'w'的地址,我们要得到字符'r'只需在字符'w'的地址上加2即可,因为arr[1]指向的类型是char跨度宽度均为1字节

问:输出多少?

1
2
3
4
5
6
7
#include<stdio.h>
int main(int argc,char *argv[]){
short *arr[3] = {"hello","world","abcdefg"};

printf("%c\n",*(arr[2]+1));
return 0;
}

运行结果:
图片

分析:
arr[2]指向类型为short宽度和跨度都为2字节

数组指针

数组指针是一个指针变量,如果分不清可以试试将指针替换为地址,即数组的地址,顾名思义他就是一个存放一个数组的地址的指针变量

案例1:

图片

1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
int main(int argc,char *argv[]){
int arr[5] = {10,20,30,40,50};
int (*p)[5];//数组指针:本质是一个指针变量,只是这个变量保存的是数组的首地址
p = &arr;

printf("sizeof(p)=%d\n",sizeof(p));//4
printf("p=%u\n",p);
printf("p+1=%u\n",p+1);
return 0;
}

运行结果:
图片

分析:
第7行代码,因为数值指针的本质就是一个指针变量,然而在32位平台下,指针变量的大小都是4字节;
第8、9行代码,因为p指向的类型就是擦掉p和*可得p的指向类型为int[5] 跨度为4*5=20字节,所以p+1加了20

拓展:取出 arr[5] = {10,20,30,40,50}; 中的 30

1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
int main(int argc,char *argv[]){
int arr[5] = {10,20,30,40,50};
int (*p)[5];//数组指针:本质是一个指针变量,只是这个变量保存的是数组的首地址
p = &arr;

printf("%d\n",*(*p+2));
printf("%d\n",p[0][2]);//*(*(p+0)+2)=*(p[0]+2)=p[0][2]
//一维数组可以看成只有一行的二维数组
return 0;
}

运行结果:
图片

对数组指针取 * 得到数组元素的地址
对数组首地址取 * 得到数组首元素的地址
*p=*&arr = arr

总结:

  1. 指针数组:本质是数组,只是数组的每个元素是指针
  2. 数组指针:本质是指针变量,只是保存的是数组的首地址(不是数组首元素的地址)