数组指针和指针数组的区别

数组指针和指针数组的区别概念 数组指针 和 指针数组 表达的是两种不同的概念 可以理解为 1 数组的指针 是一个指针 什么样的指针呢 指向数组的指针 占有内存中一个指针的存储空间 2 指针的数组 是一个数组 什么样的数组呢 存着指针的数组 占有多个指针的存储空间

欢迎大家来到IT世界,在知识的湖畔探索吧!

概念

“数组指针”和“指针数组”表达的是两种不同的概念,可以理解为:

1)数组的指针:是一个指针,什么样的指针呢?指向数组的指针,占有内存中一个指针的存储空间。

2)指针的数组:是一个数组,什么样的数组呢?存着指针的数组,占有多个指针的存储空间。

根据优先级顺序:()>[]>*,可以总结出:

1)int (*p)[n]:()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。所以数组指针也称指向一维数组的指针,即称为行指针。

2)int *p[n]:[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1是错误的,这样赋值也是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]…p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。

假设定义int (*p2)[5],()的优先级比[]高,*号和 p2 构成一个指针的定义,指针变量名为 p2,而 int 修饰的是数组的内容,即数组的每个元素。也就是说,p2 是一个指针,它指向一个包含 5 个 int 类型数据的数组,如图 1 所示。很显然,它是一个数组指针,数组在这里并没有名字,是个匿名数组。

数组指针和指针数组的区别

图1 数组指针内存分配

对于语句int *p1[5],因为[]的优先级要比*要高,所以 p1 先与[]结合,构成一个数组的定义,数组名为 p1,而int*修饰的是数组的内容,即数组的每个元素。也就是说,该数组包含 5 个指向 int 类型数据的指针,如图 2 所示,因此,它是一个指针数组。

数组指针和指针数组的区别

图2 指针数组内存分配

数组指针 (*p)[n]

指向一维数组例子:

#include <iostream> int main() { //一维数组 int a[5] = { 1, 2, 3, 4, 5 }; //步长为5的数组指针,即数组里有5个元素 int(*p)[5]; //把数组a的地址赋给p,则p为数组a的地址,则*p表示数组a本身 p = &a; //在C中,在几乎所有使用数组的表达式中,数组名的值是个指针常量,也就是数组第一个元素的地址,它的类型取决于数组元素的类型。 printf("%p\n", a); //输出数组名,一般用数组的首元素地址来标识一个数组,则输出数组首元素地址 printf("%p\n", p); //根据上面,p为数组a的地址,输出数组a的地址 printf("%p\n", *p); //*p表示数组a本身,一般用数组的首元素地址来标识一个数组 printf("%p\n", &a[0]); //a[0]的地址 printf("%p\n", &a[1]); //a[1]的地址 printf("%p\n", p[0]); //数组首元素的地址 printf("%d\n", p); //*p为数组a本身,即为数组a首元素地址,则*(*p)为值,当*p为数组首元素地址时,p表示首元素的值1 printf("%d\n", *p[0]); //根据优先级,p[0] 表示首元素地址,则*p[0]表示首元素本身,即首元素的值1 printf("%d\n", *p[1]); //随机数,不表示a[1] std::cout << sizeof(p) << std::endl; //占用一个指针的内存空间,4个字节 return 0; }

欢迎大家来到IT世界,在知识的湖畔探索吧!

指向二维数组例子:

欢迎大家来到IT世界,在知识的湖畔探索吧!#include <iostream> int main() { //一维数组 int a[3][3] = { { 1, 2, 3 }, { 6, 7, 8 } , { 9, 10, 11 } }; //步长为3的数组指针,即数组里有9个元素 int(*p)[3]; //把数组a的第一行首地址赋给p,则p为数组a[0]的地址 p = &a[0]; printf("%p\n", a); //输出数组名,一般用数组的首元素地址来标识一个数组,则输出数组首元素地址 printf("%p\n", p); //根据上面,p为数组a的地址,输出数组a的地址 printf("%p\n", *p); //*p表示数组a本身,一般用数组的首元素地址来标识一个数组 printf("%p\n", &a[0][0]); //a[0][0]的地址,第一行的首地址 printf("%p\n", &a[0]); //a[0]的地址,第一行的首地址 printf("%p\n", &a[1]); //a[1]的地址,第二行的首地址,比第一行多12字节 printf("%p\n", p[0]); //数组首元素的地址,即第一行的首地址 printf("%d\n", a[0][0]); //a[0][0]的值1 printf("%d\n", a[1][0]); //a[1][0]的值6 printf("%d\n", *p[0]); //p[0]表示第一行首地址,则*p[0]表示首元素本身,即首元素的值1 printf("%d\n", *p[1]); //p[1]表示第二行首地址,则*p[1]表示a[1][0]的值6 printf("%d\n", p); //*p为数组a本身,即为数组a首元素地址,则*(*p)为值,当*p为数组首元素地址时,p表示首元素的值1 *p++;//*p是第一行的首地址,*p++的步长是12字节,指向下一行首地址 printf("%d\n", p);//表示a[1][0]的值6 std::cout << sizeof(p) << std::endl; //占用一个指针的内存空间,4个字节 return 0; }

指针数组 *p[n]

举个例子:

#include <iostream> int main() { int a = 1; int b = 2; int* p[2]; p[0] = &a; p[1] = &b; printf("%p\n", p[0]); //a的地址 printf("%p\n", &a); //a的地址 printf("%p\n", p[1]); //b的地址 printf("%p\n", &b); //b的地址 printf("%d\n", *p[0]); //p[0]表示a的地址,则*p[0]表示a的值 printf("%d\n", *p[1]); //p[1]表示b的地址,则*p[1]表示b的值 //将二维数组赋给指针数组 int* pp[3]; //一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2],所以要分别赋值 int c[3][4]; for (int i = 0; i < 3; i++) { pp[i] = c[i]; } const char* str[3] = { "好学的梦想家best", "非常喜欢", "今日头条" };//一个数组存放了3个const char*指针 std::cout << str[0] << std::endl;//输出 "好学的梦想家best" std::cout << str[1] << std::endl;//输出 "非常喜欢" std::cout << str[2] << std::endl; //输出 "今日头条" return 0; }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/93312.html

(0)
上一篇 2024年 11月 30日 下午6:45
下一篇 2024年 11月 30日 下午7:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信