int(*p)[4]声明后的使用问题!

ImAmelie 2014-07-01 08:23:35

#include <stdio.h>
int main()
{
int a[4] = { 1, 3, 5, 7 };
int(*p)[4];
p = &a;
printf("%d\n", sizeof(p)); //4字节
printf("%d\n", sizeof(*p));//16字节
printf("%d\n", sizeof(a)); //16字节
printf("%d\n", &a[0]);//16645296
printf("%d\n", p); //16645296
printf("%d\n", p[0]); //16645296
printf("%d\n", p[1]); //16645312
printf("%d\n", p[2]); //16645312
printf("%d\n", p[3]); //16645344
printf("%d\n", *p); //16645296
printf("%d\n", *p[0]);//1
printf("%d\n", *p[1]);//-858993460
printf("%d\n", *p[2]);//1
printf("%d\n", *p[3]);//0
printf("%d\n", (*p)); //16645296
printf("%d\n", (*p)[0]);//1
printf("%d\n", (*p)[1]);//3
printf("%d\n", (*p)[2]);//5
printf("%d\n", (*p)[3]);//7
return 0;
}


我不明白的是
这里的
p p[0] p[1] p[2] p[3]
*p *p[0] *p[1] *p[2] *p[3]
(*p) (*p)[0] (*p)[1] (*p)[2] (*p)[3]
分别代表什么?
上网查了好多,指针数组我明白,但是指向一个数组的指针不是很明白!
int (*p)[4]; 不懂声明之后如果使用 是用*p 还是p还是(*p) 也不理解这三种代表什么意思?希望有高人解惑!
*p是取地址p里的值我明白,但是用在数组指针上就不明白是什么意思了。。。
...全文
410 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
PhilosNix 2015-07-02
  • 打赏
  • 举报
回复
请问,这里的lamda表达式中想要接收每一行数组的指针,为什么总是编译不通过 int *p_2d = new int[r*c]; int (*p)[c] = (int (*)[c])p_2d; for_each(&p[0],&p[r],[](int *line){cout << *line[1] << endl;}); error: no matching function for call to 'for_each(int (*)[c], int (*)[c], dynamic_array_2D(int, int)::<lambda(int*)>)' 而下面的方式: int **m; for_each(m,m+r,[&](int *line){ for_each(line,line + c,[](int &a){cout << a << " ";});}); 是可以的,也就是我也对p和p[0]还有&p[0]在此的含义由疑惑
707wk 2014-07-04
  • 打赏
  • 举报
回复
引用 5 楼 Intel0011 的回复:
[quote=引用 2 楼 zxh707wk 的回复:] [quote=引用 1 楼 Intel0011 的回复:] int a[4] = { 1, 3, 5, 7 }; int(*p)[4]; //--->首先,(*p)表明p是一个指针,指向一个一维数组,该数组有4个元素,元素的类型是int p = &a; (*p)表示p指向的一维数组的第一个元素的地址
错了,应该是
int(* p)[4]; //--->首先,(*p)表明p是一个指针,指向一个一维指针数组,该数组有4个元素,元素的类型是int*
[/quote] 自己先整明白了再来评论对错 如果你说的对,那 int * (* p)[4]; 表示什么 显然你都没搞清楚 int (* p)[4]; 和 int *p[4]; 的区别[/quote]把你那句话理解错了。。。
赵4老师 2014-07-02
  • 打赏
  • 举报
回复
//char (*(*x[3])())[5];//x是什么类型的变量?
//
//分析C语言声明,关键是搞清楚这个变量是个什么东西(函数、指针、数组),
//是函数那么剩下的就是他的参数和返回值,
//是指针那剩下部分是说明他指向什么,
//是数组剩下的部分就是说明数组的成员是什么类型。
//解析C语言声明规则:
//从左侧第一个标识符开始,按照优先级进行结合。*表示是..的指针,const表示只读的,volatile表示可变的,[]表示是数组,()表示是函数。
//
//x和[3]结合说明是一个大小为3的数组,该数组的每个元素为一类指针,该类指针指向一类函数,该类函数无参数,返回一类指针,该类指针指向一个大小为5的char型数组
#include <stdio.h>
#include <typeinfo.h>
char num[5];
char (*x00())[5] {
    return #
}
int main() {
    char (*x000)[5];//返回值
    char (*(x00)())[5];//函数原型,参数为空,返回值为指针
    char (*(*x0)())[5];//数组的元素,是个函数指针
    char (*(*x[3])())[5];//是个数组,大小为3

    x0 = x00;
    x[0] = x0;
    x[1] = x0;
    x[2] = x0;
    printf("typeid(x).name() is %s\n",typeid(x).name());
    return 0;
}
//typeid(x).name() is char (* (__cdecl**)(void))[5]
初見的畫面 2014-07-02
  • 打赏
  • 举报
回复
引用 1 楼 Intel0011 的回复:
int a[4] = { 1, 3, 5, 7 }; int(*p)[4]; //--->首先,(*p)表明p是一个指针,指向一个一维数组,该数组有4个元素,元素的类型是int p = &a; (*p)表示p指向的一维数组的第一个元素的地址
这个就是正确的。 指向数组的指针就是说一个指针指向了整个数组,也就是说这个指针指向的是整个数组的空间,此时对这个指针进行自加操作得到的地址就是向后移动整个数组长度的地址。
一根烂笔头 2014-07-02
  • 打赏
  • 举报
回复
数组int p[4] 指针的数组int *p[4]——这是个数组,4个成员,每个成员类型都是int * 数组指针int (*p)[4]——这是个单变量,不是个数组,数据类型int (*)[4],它赋值为int p[4]这样的数组 骚年,明白否?
黑娃 2014-07-02
  • 打赏
  • 举报
回复
int(*p)[4];// p是一个指针,指向int型数组,数组大小是4 p = &a;// p指向了数组a的地址的地址,但一次++p操作会让p增加数组大小的字节,也就是4*4=16,虽然都是指向数组地址,但这就是p=&a和p=a的不同之处 printf("%d\n", sizeof(p)); //4字节 指针都是4字节,32位系统中 printf("%d\n", sizeof(*p));//16字节 *p是数组首地址,等价于a,也就是计算了数组的长度 printf("%d\n", sizeof(a)); //16字节 同上 printf("%d\n", &a[0]);//16645296 数组首地址 printf("%d\n", p); //16645296 上面已经解释了,p是数组首地址的地址,地址值等同于数组首地址 printf("%d\n", p[0]); //16645296 对该二级地址取值,等价于*p,这时它真正代表了数组首地址,升级为一级地址 printf("%d\n", p[1]); //16645312 等价于++p,仍然是个地址,可是加了数组的长度16 printf("%d\n", p[2]); //16645312 同上,估计的写错了,应该是16645328 printf("%d\n", p[3]); //16645344 同上 printf("%d\n", *p); //16645296 解释过了 printf("%d\n", *p[0]);//1 等价于在p【0】上取值,当然是数组的第一个元素值 printf("%d\n", *p[1]);//-858993460 p[1]已经指向了一个位置的地址,其值也位置 printf("%d\n", *p[2]);//1 P[2]更加未知 printf("%d\n", *p[3]);//0 更加未知 printf("%d\n", (*p)); //16645296 解释过了 printf("%d\n", (*p)[0]);//1 // 首先取值(*p),变成了一级地址,这时候++就正常了,为一个int的值,所以取到了数组第一个值 printf("%d\n", (*p)[1]);//3// 取到了第二个值 printf("%d\n", (*p)[2]);//5 不解释 printf("%d\n", (*p)[3]);//7 不解释。。。 综上所述,在你懂得了指针指向数组的前提下,你还要明白p=&a,p=a的区别,都是地址,但前者的++操作会等于数组总长度,后者则是一个数组单元长度,此外,前者由于是地址的地址,所以可以取两次值。
赵4老师 2014-07-02
  • 打赏
  • 举报
回复
不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质, 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。
均陵鼠侠 2014-07-02
  • 打赏
  • 举报
回复
骚年,提向数组的指针不明白的话,怎么帮你都没用。
ImAmelie 2014-07-02
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
//char (*(*x[3])())[5];//x是什么类型的变量?
//
//分析C语言声明,关键是搞清楚这个变量是个什么东西(函数、指针、数组),
//是函数那么剩下的就是他的参数和返回值,
//是指针那剩下部分是说明他指向什么,
//是数组剩下的部分就是说明数组的成员是什么类型。
//解析C语言声明规则:
//从左侧第一个标识符开始,按照优先级进行结合。*表示是..的指针,const表示只读的,volatile表示可变的,[]表示是数组,()表示是函数。
//
//x和[3]结合说明是一个大小为3的数组,该数组的每个元素为一类指针,该类指针指向一类函数,该类函数无参数,返回一类指针,该类指针指向一个大小为5的char型数组
#include <stdio.h>
#include <typeinfo.h>
char num[5];
char (*x00())[5] {
    return #
}
int main() {
    char (*x000)[5];//返回值
    char (*(x00)())[5];//函数原型,参数为空,返回值为指针
    char (*(*x0)())[5];//数组的元素,是个函数指针
    char (*(*x[3])())[5];//是个数组,大小为3

    x0 = x00;
    x[0] = x0;
    x[1] = x0;
    x[2] = x0;
    printf("typeid(x).name() is %s\n",typeid(x).name());
    return 0;
}
//typeid(x).name() is char (* (__cdecl**)(void))[5]

#include <stdio.h>

int main()

{

	char(*(*x[3])())[5];

	(char (*)[5]) (*y[3])();

	return 0;

}
//前几步我都看懂了 x是一个数组,元素是指针,而且是函数指针
//函数返回值我看不懂了 看我第9行 y是一个数组,元素是指针,是函数指针,函数的返回值是指向一维字符数组的指针
//问题是 编译起来 第9行就报错 我也不知道哪里不对 希望你能帮我看看!
Intel0011 2014-07-02
  • 打赏
  • 举报
回复
引用 2 楼 zxh707wk 的回复:
[quote=引用 1 楼 Intel0011 的回复:] int a[4] = { 1, 3, 5, 7 }; int(*p)[4]; //--->首先,(*p)表明p是一个指针,指向一个一维数组,该数组有4个元素,元素的类型是int p = &a; (*p)表示p指向的一维数组的第一个元素的地址
错了,应该是
int(* p)[4]; //--->首先,(*p)表明p是一个指针,指向一个一维指针数组,该数组有4个元素,元素的类型是int*
[/quote] 自己先整明白了再来评论对错 如果你说的对,那 int * (* p)[4]; 表示什么 显然你都没搞清楚 int (* p)[4]; 和 int *p[4]; 的区别
cao_julians 2014-07-02
  • 打赏
  • 举报
回复
引用 楼主 u013491662 的回复:

#include <stdio.h>
int main()
{
	int a[4] = { 1, 3, 5, 7 };
	int(*p)[4];
	p = &a;
	printf("%d\n", sizeof(p)); //4字节
	printf("%d\n", sizeof(*p));//16字节
	printf("%d\n", sizeof(a)); //16字节
	printf("%d\n", &a[0]);//16645296
	printf("%d\n", p);    //16645296
	printf("%d\n", p[0]); //16645296
	printf("%d\n", p[1]); //16645312
	printf("%d\n", p[2]); //16645312
	printf("%d\n", p[3]); //16645344
	printf("%d\n", *p);   //16645296
	printf("%d\n", *p[0]);//1
	printf("%d\n", *p[1]);//-858993460
	printf("%d\n", *p[2]);//1
	printf("%d\n", *p[3]);//0
	printf("%d\n", (*p)); //16645296
	printf("%d\n", (*p)[0]);//1
	printf("%d\n", (*p)[1]);//3
	printf("%d\n", (*p)[2]);//5
	printf("%d\n", (*p)[3]);//7
	return 0;
}
我不明白的是 这里的 p p[0] p[1] p[2] p[3] *p *p[0] *p[1] *p[2] *p[3] (*p) (*p)[0] (*p)[1] (*p)[2] (*p)[3] 分别代表什么? 上网查了好多,指针数组我明白,但是指向一个数组的指针不是很明白! int (*p)[4]; 不懂声明之后如果使用 是用*p 还是p还是(*p) 也不理解这三种代表什么意思?希望有高人解惑! *p是取地址p里的值我明白,但是用在数组指针上就不明白是什么意思了。。。
p = &a; //p指向了a整个数组 printf("%d\n", sizeof(p)); //4字节 //p指针变量的尺寸是4字节 printf("%d\n", sizeof(*p));//16字节 //p指向的a数组尺寸是4*4个字节 printf("%d\n", sizeof(a)); //16字节 //同上 printf("%d\n", &a[0]);//16645296 //a数组首元素的地址(指针值)是16645296 printf("%d\n", p); //16645296 //a数组首址是16645296。注意数组首址和首元素地址值同、类型不同 printf("%d\n", p[0]); //16645296 //这是首元素的地址 printf("%d\n", p[1]); //16645312 //这里语法上无错,但语义上有错,这是a数组之后存储单元的地址 printf("%d\n", p[2]); //16645312 //这里语法上无错,但语义上有错,这是a数组之后存储单元的地址--另外输出应该是16645328 printf("%d\n", p[3]); //16645344 //这里语法上无错,但语义上有错,这是a数组之后存储单元的地址 printf("%d\n", *p); //16645296 //p是指向a数组的首址,*p就是指向a数组首元素的地址 printf("%d\n", *p[0]);//1 //这是首元素的值 printf("%d\n", *p[1]);//-858993460 //这是越界访问 printf("%d\n", *p[2]);//1 //这是越界访问 printf("%d\n", *p[3]);//0 //这是越界访问 printf("%d\n", (*p)); //16645296 printf("%d\n", (*p)[0]);//1 //p<=&a,则*p就是a(即&a[0]),(*p)[0]就是a[0] printf("%d\n", (*p)[1]);//3 //p<=&a,则*p就是a(即&a[0]),(*p)[1]就是a[1] printf("%d\n", (*p)[2]);//5 //p<=&a,则*p就是a(即&a[0]),(*p)[2]就是a[2] printf("%d\n", (*p)[3]);//7 //p<=&a,则*p就是a(即&a[0]),(*p)[3]就是a[3] ===================================================================== p=&a a[0] <--------p[0] <---p,但这两个指针的类型不同 a[1] a[2] a[3] ?[0] <-------p[1] ?[1] ?[2] ?[3]
ImAmelie 2014-07-01
  • 打赏
  • 举报
回复
说错了望指正!
ImAmelie 2014-07-01
  • 打赏
  • 举报
回复
总结下,是不是这样 int (*p)[4] 他只在内存中开辟了4字节存储空间用来存地址 变量名为p 类型为int (*)[4] 存储的地址为4元素一维数组地址(虽然地址是一维数组的首元素地址,但他是行指针) *p代表一维数组首元素的地址 (*p)[0] *(*p) 代表一维数组中下标为0的值 (*p)[1] *(*p+1) 代表一维数组中下标为1的值 (*p)[2] *(*p+2) 代表一维数组中下标为2的值 (*p)[3] *(*p+3) 代表一维数组中下标为3的值
707wk 2014-07-01
  • 打赏
  • 举报
回复
引用 1 楼 Intel0011 的回复:
int a[4] = { 1, 3, 5, 7 }; int(*p)[4]; //--->首先,(*p)表明p是一个指针,指向一个一维数组,该数组有4个元素,元素的类型是int p = &a; (*p)表示p指向的一维数组的第一个元素的地址
错了,应该是
int(* p)[4]; //--->首先,(*p)表明p是一个指针,指向一个一维指针数组,该数组有4个元素,元素的类型是int*
Intel0011 2014-07-01
  • 打赏
  • 举报
回复
int a[4] = { 1, 3, 5, 7 }; int(*p)[4]; //--->首先,(*p)表明p是一个指针,指向一个一维数组,该数组有4个元素,元素的类型是int p = &a; (*p)表示p指向的一维数组的第一个元素的地址

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧