C语言之数组指针

简介: C语言之数组指针

5.1.10 数组指针

1、二维数组

二维数组,有行,有列。二维数组可以看成有多个一维数组构成的,是多个一维数组的集合,可以认 为二维数组的每一个元素是个一维数组。

例:

int a[3][5]; 定义了一个 3 行 5 列的一个二维数组。

可以认为二维数组 a 由 3 个一维数组构成,每个元素是一个一维数组。

回顾: 数组的名字是数组的首地址,是第 0 个元素的地址,是个常量,数组名字加 1 指向下个元素 二维数组 a 中 ,a+1 指向下个元素,即下一个一维数组,即下一行。

例 14:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[3][5];
printf("a=%p\n",a);
printf("a+1=%p\n",a+1);
return 0;
}

2、数组指针的概念:

本身是个指针,指向一个数组,加 1 跳一个数组,即指向下个数组。

3、数组指针的定义方法:

指向的数组的类型(*指针变量名)[指向的数组的元素个数]

int (*p)[5];//定义了一个数组指针变量 p,p 指向的是整型的有 5 个元素的数组

p+1 往下指 5 个整型,跳过一个有 5 个整型元素的数组

例 15:
#include<stdio.h>
int main()
{
int a[3][5];//定义了一个 3 行 5 列的一个二维数组
int(*p)[5];//定义一个数组指针变量 p,p+1 跳一个有 5 个元素的整型数组
printf("a=%p\n",a);//第 0 行的行地址
printf("a+1=%p\n",a+1);//第 1 行的行地址,a 和 a +1 差 20 个字节
p=a;
printf("p=%p\n",p);
printf("p+1=%p\n",p+1);//p+1 跳一个有 5 个整型元素的一维数组
return 0;
}
例 16:数组指针的用法 
#include<stdio.h>
void fun(int(*p)[5],int x,int y)
{
p[0][1]=101;
}
int main()
{
int i,j;
int a[3][5];
fun(a,3,5);
for(i=0;i<3;i++)
{
for(j=0;j<5;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
}

4、各种数组指针的定义:

(1)、一维数组指针,加 1 后指向下个一维数组

int(*p)[5] ; // 配合每行有 5 个 int 型元素的二维数组来用

int a[3][5]

int b[4][5]

int c[5][5]

int d[6][5]

…..

p=a;

p=b;

p=c;

p=d;

都是可以的~~~~

(2)、二维数组指针,加 1 后指向下个二维数组

int(*p)[4][5];

配合三维数组来用,三维数组中由若干个 4 行 5 列二维数组构成

int a[3][4][5];

int b[4][4][5];

int c[5][4][5];

int d[6][4][5];

这些三维数组,有个共同的特点,都是有若干个 4 行 5 的二维数组构成。

p=a;

p=b;

p=c;

p=d

例 17:
#include<stdio.h>
int main()
{
int a[3][4][5];
printf("a=%p\n",a);
printf("a+1=%p\n",a+1);//a 和 a+1 地址编号相差 80 个字节
//验证了 a+1 跳一个 4 行 5 列的一个二维数组
int(*p)[4][5];
p=a;
printf("p=%p\n",p);
printf("p+1=%p\n",p+1);//p 和 p+1 地址编号相差也 80 个字节
return 0;
}

5、三维数组指针,加 1 后指向下个三维数组

int(*p)[4][5][6];

p+1 跳一个三维数组;

什么样的三维数组啊?

由 4 个 5 行 6 列的二维数组构成的三维数组

配合: int a[7][4][5][6];

6、四维数组指针,加 1 后指向下个四维数组,以此类推。。。。

7、注意: 容易混淆的概念:

指针数组:是个数组,有若干个相同类型的指针构成的集合

int *p[10];

数组 p 有 10 个 int *类型的指针变量构成,分别是 p[0] ~p[9]

数组指针:本身是个指针,指向一个数组,加 1 跳一个数组

int (*p)[10];

P 是个指针,p 是个数组指针,p 加 1 指向下个数组,跳 10 个整形。

指针的指针:

int **p;//p 是指针的指针 int *q; p=&q;

8、数组名字取地址:变成 数组指针 一维数组名字取地址,变成一维数组指针,即加 1 跳一个一维数组

国际 a[10];

a+1 跳一个整型元素,是 a[1]的地址 a 和 a+1 相差一个元素,4 个字节 &a 就变成了一个一维数组指针,是 int(*p)[10]类型的。

(&a) +1 和&a 相差一个数组即 10 个元素即 40 个字节。

例 18:
#include<stdio.h>
int main()
{
int a[10];
printf("a=%p\n",a);
printf("a+1=%p\n",a+1);
printf("&a=%p\n",&a);
printf("&a +1=%p\n",&a+1);
return 0;
}

a 是个 int *类型的指针,是 a[0]的地址。

&a 变成了数组指针,加 1 跳一个 10 个元素的整型一维数组 在运行程序时,大家会发现 a 和&a 所代表的地址编号是一样的,即他们指向同一个存储单元,但是 a 和&a 的指针类型不同。

例 19:
int a[4][5];
a+1 跳 5 个整型
(&a)+1 跳 4 

总结:c 语言规定,数组名字取地址,变成了数组指针。 加 1 跳一个数组。

9、数组名字和指针变量的区别:

国际 a[5];int *p;p=a;相同点:

a 是数组的名字,是 a[0]的地址,p=a 即 p 保存了 a[0]的地址,即 a 和 p 都指向 a[0],所以在引用数组 元素的时候,a 和 p 等价

引用数组元素回顾: a[2]、*(a+2)、p[2]、*(p+2) 都是对数组 a 中 a[2]元素的引用。

#include<stdio.h>
int main()
{
int a[5] = { 0,1,2,3,4 };
int* p;
p = a;
printf("a[2]=%d\n",a[2]);
printf(" * (a + 2) = % d\n",*(a+2));
printf("p[2]=%d\n", p[2]);
printf(" * (p + 2) = % d\n", *(p + 2));
return 0;
}

不同点:

1、 a 是常量、p 是变量 可以用等号’=’给 p 赋值,但是不能用等号给 a 赋值

2、 对 a 取地址,和对 p 取地址结果不同 因为 a 是数组的名字,所以对 a 取地址结果为数组指针。 p 是个指针变量,所以对 p 取地址(&p)结果为指针的指针。

例:int a[5]={0,1,2,3,4}; int *p=a; 假如 a[0]的地址为 0x00002000,p

1、&p 是指针的指针,为 int **类型,结果为 0x00003000,&p +1,往后指向一个 int* 类型的指 针,地址编号差 4

2、&a 结果是数组指针,为 int(* )[5]类型,结果还是 0x00002000,&a +1 ,往后指一个数组(有 5 个整型元素的一维数组),地址编号差 2

例 20:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[5];
int *p;
p=a;
printf("a=%p\n",a);
printf("&a=%p\n",&a);
printf("&a +1 =%p\n",&a +1);
printf("p=%p\n",p);
printf("&p=%p\n",&p);
printf("&p +1=%p\n",&p +1);
return 0;
}

10、数组指针取* 数组指针取 * ,并不是取值的意思,而是指针的类型发生变化: 一维数组指针取* ,结果为它指向的一维数组第 0 个元素的地址,它们还是指向同一个地方。 二维数组指针取 *,结果为一维数组指针,它们还是指向同一个地方。 三维数组指针取*,结果为二维数组指针,它们还是指向同一个地方。 多维以此类推

例 21:
#include<stdio.h>
int main()
{
int a[3][5];
int(*p)[5];
p = a;
printf("a=%p\n", a);//a 是一维数组指针,指向第 0 个一维数组,即第 0 行
printf("*a=%p\n", *a);//*a 是 第 0 行第 0 个元素的地址,即 &a[0][0]
printf("*a +1=%p\n", *a + 1);//*a +1 是第 0 行第 1 个元的地址,即&a[0][1]
printf("p=%p\n",p);//p 是一维数组指针,指向第 0 个一维数组,即第 0 行
printf("*p=%p\n",*p);//*p 是第 0 行第 0 个元素的地址,即 &a[0][0]
printf("*p +1=%p\n", *p + 1);//*p +1 是第 0 行第 1 个元的地址,即&a[0][1]
return 0;
}
相关文章
|
18天前
|
安全 C语言
【C语言】如何规避野指针
【C语言】如何规避野指针
20 0
|
18天前
|
存储 编译器 C语言
C语言之数组
C语言之数组
24 0
|
19天前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
8天前
|
C语言
c语言指针总结
c语言指针总结
14 1
数组指针、函数指针、指针数组、函数 指针数组、指针函数详细总结
数组指针、函数指针、指针数组、函数 指针数组、指针函数详细总结
|
8天前
|
机器学习/深度学习 C语言
C语言三维数组的创建
该代码片段展示了如何在C语言中创建一个动态的3D数组。由于`n`在编译时未知,不能直接声明为`int f[n][n][n]`。正确的方法是使用`malloc`进行动态内存分配。首先分配`n`个`int **`,然后对每一层分配`n`个`int *`,最后每个元素分配`n`个`int`。之后可以使用这个3D数组,并在完成后正确释放内存。
11 2
|
14天前
|
存储 程序员 C语言
【C 言专栏】C 语言指针的深度解析
【4月更文挑战第30天】C 语言中的指针是程序设计的关键,它如同一把钥匙,提供直接内存操作的途径。指针是存储其他变量地址的变量,通过声明如`int *ptr`来使用。它们在动态内存分配、函数参数传递及数组操作中发挥重要作用。然而,误用指针可能导致错误,如空指针引用和内存泄漏。理解指针的运算、与数组和函数的关系,以及在结构体中的应用,是成为熟练 C 语言程序员的必经之路。虽然挑战重重,但掌握指针将增强编程效率和灵活性。不断实践和学习,我们将驾驭指针,探索更广阔的编程世界。
|
15天前
|
算法 搜索推荐 程序员
C语言中的函数指针和回调函数
C语言中的函数指针和回调函数
10 2
|
18天前
|
存储 编译器 C语言
【C语言】初步解决指针疑惑
【C语言】初步解决指针疑惑
7 0
|
19天前
|
存储 C语言
指针深入解析(C语言基础)带你走进指针,了解指针
指针深入解析(C语言基础)带你走进指针,了解指针