C 语言 第五章 指针(6)
目录
指针与数组
一维数组与指针
数组的指针变量
使用指针访问数组的元素
&数组名
数组指针 vs 指针数组
数组指针:
指针数组:
指针数组的使用
格式:
举例:
字符串数组的表示
举例1:
方式1:使用二维字符数组
方式2:使用字符指针数组
遍历字符指针数组:
指针与数组
- 指针运算如果只是对单个变量操作其意义和作用不是很明显,
- 在前面我们提到指针的很多操作都是和数组有关的,
- 在一个连续存储空间中能发挥巨大作用,所以在此将指针在数组中的应用作为专题。
一维数组与指针
数组的指针变量
int a[10]={2,4,6,8,10,12,14,16,18,20};
int* p; //定义p为指向整型变量的指针变量
p = &a[0]; //把a[0]元素的地址赋给指针变量p
如下几个写法是等价的:
int* p = &a[0];
int* p = a; //a不代表整个数组,所以这里不是将数组a赋给p,而代表数组元素a[0]的首地址。
使用指针访问数组的元素
如果指针变量p的初值为&a[0],则:
- p+i和a+i就是数组元素a[i]的地址。或者说,它们指向a数组序号为i的元素。
- (p+i)或 (a+i)是p+i或a+i所指向的数组元素的值,即a[i]的值。
代码示例:
#include "stdio.h"
void initArr(int arr[], int len) {
// 数组作为参数传递时,在函数内部不能通过数组名计算长度,需要调用时,把长度传递过来
for (int i = 0; i < len; ++i) {
arr[i] = i + 1; //1,2,3,4,5
}
}
int main() {
//声明一个数组 ,写一个函数,在函数中对数组进行初始化赋值操作
int arr[5]; initArr(arr, 5); //数组在作为参数传递时,数组名降级为首元素的位置
for (int i = 0; i < sizeof(arr)/sizeof(int); ++i) {
printf("%d\t", arr[i]); //1,2,3,4,5 } return 0; }
#include "stdio.h"int main() {// 数组指针变量int arr[5] = {[0]: 1, [1]: 2, [2]: 3, [3]: 4, [4]: 5};// 声明数组指针变量int* p1 = arr; // 数组名,默认是数组中首元素的位置int* p2 = &arr[0]; // 数组中的元素进行访问// 传统做法for (int i = 0; i < sizeof(arr) / sizeof(int); ++i) {printf("%d\t", arr[i]);}// 通过指针操作数组,找最大值int a[5] = {[0]: 33, [1]: 12, [2]: 25, [3]: 9, [4]: 18};int* p = a; int max = a[0];for (int i = 0; i < sizeof(a) / sizeof(int); ++i) {if (max < *(p + i)) {max = *(p + i);}} printf("最大值%d", max);return 0;}
&数组名
int a[5] = {1,2,3,4,5};
printf("%p\n", a); //000000000034fa50
printf("%p\n", &a); //000000000034fa50
发现,数组名 和 &数组名 打印的地址是一样的。
举例:
#include <stdio.h>int main() {
int a[5] = {1,2,3,4,5};
printf("a = %p\n", a); //000000cade5ff750 a表示a[0]元素的地址
printf("&a= %p\n", &a); //000000cade5ff750 &a表示a数组的地址
printf("a+1 = %p\n", a + 1); //000000cade5ff754 a + 1:表示a[1]元素的地址
printf("&a+1= %p\n", &a + 1); //000000cade5ff764return 0;
}
注:&a理解为 数组的地址,而不要理解为数组首元素a[0]的地址。
本例中&a数组的地址+1,跳过整个数组的大小,所以&a+1相对于&a的差值是20。
因为地址是16进制的,764 - 750 = 14,16进制的14等于20。
数组指针 vs 指针数组
数组指针:
当指针变量里存放一个数组的首地址时,此指针变量称为指向数组的指针变量,简称数组指针。
数组指针是指针?还是数组?
答案是:指针。 |
- 整型指针:int* pint; 能够指向整型数据的指针。
- 浮点型指针:float* pf; 能够指向浮点型数据的指针。
- 数组指针:能够指向数组的指针。
指针数组:
定义:
数组是用来存放一系列相同类型的数据,当然数组也可以用来存放指针,这种用来存放指针的数组被称为指针数组,它要求存放在数组中指针的数据类型必须一致。
问题:指针数组是指针还是数组?
答案:是数组。是存放指针的数组。 |
指针数组的使用
格式:
数据类型* 指针数组名[大小]; |
举例:
int* arr[5];
注:arr是一个数组,有5个元素,每个元素是一个整型指针,需要使用下标来区分。
元素类型
| int * | arr[0] |
| int * | arr[1] |
arr | int * | arr[2] |
| int * | arr[3] |
| int * | arr[4] |
举例:
int main() { int a = 1; int b = 2; int c = 3; int d = 4; int e = 5; int* pa = &a; int* pb = &b; int* pc = &c; int* pd = &d; int* pe = &e; int* arr[] = {pa, pb, pc, pd, pe}; //定义一个int类型的指针数组 for(int i = 0; i < 5; i++){ printf("%d ", *arr[i]); } return 0;
}
字符串数组的表示
如果一个数组的每个成员都是一个字符串,则构成了字符串数组。
字符串数组有两种表示方式:
① 二维字符数组;
② 字符指针数组。
举例1:
方式1:使用二维字符数组
char fruit[5][7]={"Apple","orange","Grape","Pear","Peach"};
char weekdays[7][10] = { "Monday", "Tuesday", "wednesday", "Thursday", "Friday", "Saturday", "Sunday"
};
- 字符串数组,一共包含7个字符串,所以第一维的长度是7。其中,最长的字符串的长度是10(含结尾的终止符 \0 ),所以第二维的长度统一设为10。
- 思考:数组的第二维,长度统一定为10,有点浪费空间,因为大多数成员的长度都小于10。解决方法就是把数组的第二维,从字符数组改成字符指针。
方式2:使用字符指针数组
char* weekdays[7] = { "Monday", "Tuesday", "wednesday", "Thursday", "Friday", "Saturday", "Sunday"
};
上述字符串数组,其实是一个一维数组,成员是7个字符指针,每个指针指向一个字符串(字符数组)。
遍历字符指针数组:
for (int i = 0; i < 7; i++) { printf("%s\n", weekdays[i]);
}