user-0 提问: 二维数组与二级指针

回复:
user: user-1
content: 引用 29 楼 sholber 的回复:[quote=引用 25 楼 u013061236 的回复:] [quote=引用 13 楼 sholber 的回复:] 代码是错的 不可以用二级指针 进行遍历   你看到的 只是一个巧合 刚刚好 int* 和 int 大小一样    你试试这段代码  ---------------------------------------------------------------------- 你就不要添乱了，他的错在于根本不懂指针，本质上不是类型的问题。 char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 你这代码有问题啊，既然是char数组，你往里放整数，很明显不会是你想象的样子，如果都解释成字符，绝对没有问题[/quote]  char属于整数类型。 显然你这最基础的东西都不明白。[/quote]  好吧，当我啥也没说，最起码你放进去3，取出来的不是3，只需要知道这一点就行了

user: user-2
content: 代码是错的 不可以用二级指针 进行遍历   你看到的 只是一个巧合 刚刚好 int* 和 int 大小一样    你试试这段代码  ---------------------------------------------------------------------- 你就不要添乱了，他的错在于根本不懂指针，本质上不是类型的问题。 char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0;

user: user-2
content: 引用 30 楼 songzhichao4444 的回复: char a[3][3] = {1,2,3,4,5,6,7,8,9};     char **p = (char**)a; 	char ***q = (char***)a;     int i,j;   //  puts(""); 	/** 	*两个for循环的结果是一样的。 	*/     for(i=0;i<3;i++)     {         printf("p+i d :%d \n ",(p+i));     }  	for(i=0;i<3;i++)     {         printf("q+i d :%d \n ",(q+i));     } 两个for循环输出的结果是一致的，他们每次都跳过一个指针的长度，windows下为4个字节，linux下为8个字节。 但是为什么，下面的两个输出结果的秩却是不一样的？？？ 	 char *u = （char*）a; for(i=0;i<9;i++)// 1 2 3 4  5 6 7  8 9 {   printf("%c",*(a+i)+'0'); }  for(i=0;i<3;i++)     {         printf("q+i c:%c \n ",*(q+i)+'0');//乱码？？？？？？     } /**/for(i=0;i<3;i++)     {         printf("p+i c:%c \n ",*(p+i)+'0');//1  5  9 每次跳过指针个长度     } 上面的循环前两个可以输出结果，为什么第三个for循环输出乱码？？？我一开始的问题应该可以解释这个问题，但是我第一个问题依然没搞明白。希望大家多给我一些指点。谢谢！ 前面说了那么多，你都还没明白，看来你很难明白了。

user: user-2
content: int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};     int *b = (int*)a; /* **以上，编译器什么也没做，都是你在做。编译器只知道，b是指向int的指针，其它什么 **也不知道了。以后，任何针对b的操作都只按指针运算的规则进行，而不管它实际上指 **向的地方是一个int[3][3]。 **也就是说，强制类型转换尽管是合法的，但丢失了和数组有关的信息，比 **如数组的大小（维度）之类的。在这种情况下，*b是一个int，而*(b+i)是另外的某个int。*/ int **p = (int**)a; /* **道理同上。p是指向指针的指针。在这种情况下，*p的结果是指向int的指针，*(p+i)是 **另外的某个指向int的指针。printf("%d  ",*(p+i));是将指针的值转换成整数打印出来。 **不过荒谬和搞笑的是，这个值其实是原数组a的内容，而不是真正的指针值。造成这种 **现象的原因，只是程序员自己搞怪，欺骗自己而已。 */

user: user-3
content: 引用 8 楼 songzhichao4444 的回复:sholber 均陵鼠侠貌似没有看明白我的问题，我的重点是 int a[3][3]; int **b = (int**)a; 以及int *b = (int*a);为什么可以将a强制转换成一个二级指针 #include<stdio.h> int main(void) { 	int **p = (int**)a;//二级指针，编译器到底做了什么，想不明白？？？  	for(i=0;i<9;i++)//对这个二级指针可以进行遍历，为什么？？结果：1 2 3 4 5 6 7 8 9 	{ 		printf("%d  ",*(p+i)); 	} } 问题在代码中，谢谢大神的指教。 代码是错的 不可以用二级指针 进行遍历  你看到的 只是一个巧合 刚刚好 int* 和 int 大小一样   你试试这段代码  #include<stdio.h> int main(void) {     char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)     {         printf("%d  ",*(b+i));     }     puts("");     for(i=0;i<9;i++)     {         printf("%d  ",*(p+i));     }     return 0; }

user: user-2
content: sholber 均陵鼠侠貌似没有看明白我的问题，我的重点是  int a[3][3];  int **b = (int**)a;  以及int *b = (int*a);为什么可以将a强制转换成一个二级指针 ---------------------------------------------------------------------------- 不是朕不明白，汝自糊涂耳。朕已经说得很明白了，C标准规定： 1，除非做为sizeof和一元&运算符的操作数，数组名将被转换为指向其首元素的指针； 2，一个指向对象类型的指针可以转换为指向另一种不同的对象类型的指针，……，转换回来后，结果和原先的指针相等； 3，一个指向任何对象类型的指针可以转换为void指针并转换回来，结果和原始指针相等。 以上三点，请瘘猪自己对照一下。

user: user-0
content: 当然我这种使用方式是极其不合理的并且是错误的。我知道二维数组、数组指针这些基本的东西。但是对8#中提到的问题想不明白。可能自己已经进入了某种思考的死角了吧，现在出不来了。我真新想弄明白8#中我提出问题的原理。

user: user-0
content: sholber 均陵鼠侠貌似没有看明白我的问题，我的重点是 int a[3][3]; int **b = (int**)a; 以及int *b = (int*a);为什么可以将a强制转换成一个二级指针 #include<stdio.h> int main(void) { 	int a[3][3] = {1,2,3,4,5,6,7,8,9}; 	int *b = (int*)a;//一级指针 	int **p = (int**)a;//二级指针，编译器到底做了什么，想不明白？？？ 	int i,j; 	for(i=0;i<9;i++) 	{ 		printf("%d  ",*(b+i)); 	} 	 	for(i=0;i<9;i++)//对这个二级指针可以进行遍历，为什么？？结果：1 2 3 4 5 6 7 8 9 	{ 		printf("%d  ",*(p+i)); 	} 	return 0; } 问题在代码中，谢谢大神的指教。

user: user-0
content: char a[3][3] = {1,2,3,4,5,6,7,8,9};     char **p = (char**)a; 	char ***q = (char***)a;     int i,j;   //  puts(""); 	/** 	*两个for循环的结果是一样的。 	*/     for(i=0;i<3;i++)     {         printf("p+i d :%d \n ",(p+i));     }  	for(i=0;i<3;i++)     {         printf("q+i d :%d \n ",(q+i));     } 两个for循环输出的结果是一致的，他们每次都跳过一个指针的长度，windows下为4个字节，linux下为8个字节。 但是为什么，下面的两个输出结果的秩却是不一样的？？？ 	 char *u = （char*）a; for(i=0;i<9;i++)// 1 2 3 4  5 6 7  8 9 {   printf("%c",*(a+i)+'0'); }  for(i=0;i<3;i++)     {         printf("q+i c:%c \n ",*(q+i)+'0');//乱码？？？？？？     } /**/for(i=0;i<3;i++)     {         printf("p+i c:%c \n ",*(p+i)+'0');//1  5  9 每次跳过指针个长度     } 上面的循环前两个可以输出结果，为什么第三个for循环输出乱码？？？我一开始的问题应该可以解释这个问题，但是我第一个问题依然没搞明白。希望大家多给我一些指点。谢谢！

user: user-2
content: 引用 25 楼 u013061236 的回复:[quote=引用 13 楼 sholber 的回复:] 代码是错的 不可以用二级指针 进行遍历   你看到的 只是一个巧合 刚刚好 int* 和 int 大小一样    你试试这段代码  ---------------------------------------------------------------------- 你就不要添乱了，他的错在于根本不懂指针，本质上不是类型的问题。 char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 你这代码有问题啊，既然是char数组，你往里放整数，很明显不会是你想象的样子，如果都解释成字符，绝对没有问题[/quote]  char属于整数类型。 显然你这最基础的东西都不明白。

user: user-2
content: 你能说void ** p存在的意义就是为了要** p吗？

user: user-2
content: 引用 26 楼 user-3 的回复:[quote=引用 23 楼 sholber 的回复:] 你是从哪里看到程序做了 **操作 ++操作 +10操作？有吗？ 臆想是要不得的，只要程序没有语法问题，你就不能说它没有意义。 我没说程序没意义  我说的变量p 没意义  程序没做 ** 操作  但是 做 **操作是 变量p 存在的意义 之一  对于这个变量p 他什么操作都不要 那么我说这个变量 没意义 有何不可? [/quote]  不能这么说啊。 你能说void * p存在的意义就是为了要** p吗？

user: user-3
content: 引用 23 楼 sholber 的回复:你是从哪里看到程序做了 **操作 ++操作 +10操作？有吗？ 臆想是要不得的，只要程序没有语法问题，你就不能说它没有意义。 我没说程序没意义  我说的变量p 没意义  程序没做 ** 操作  但是 做 **操作是 变量p 存在的意义 之一  对于这个变量p 他什么操作都不要 那么我说这个变量 没意义 有何不可?

user: user-1
content: 引用 13 楼 sholber 的回复:代码是错的 不可以用二级指针 进行遍历   你看到的 只是一个巧合 刚刚好 int* 和 int 大小一样    你试试这段代码  ---------------------------------------------------------------------- 你就不要添乱了，他的错在于根本不懂指针，本质上不是类型的问题。 char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 你这代码有问题啊，既然是char数组，你往里放整数，很明显不会是你想象的样子，如果都解释成字符，绝对没有问题

user: user-1
content: 引用 8 楼 songzhichao4444 的回复:sholber 均陵鼠侠貌似没有看明白我的问题，我的重点是 int a[3][3]; int **b = (int**)a; 以及int *b = (int*a);为什么可以将a强制转换成一个二级指针 #include<stdio.h> int main(void) { 	int a[3][3] = {1,2,3,4,5,6,7,8,9}; 	int *b = (int*)a;//一级指针 	int **p = (int**)a;//二级指针，编译器到底做了什么，想不明白？？？ 	int i,j; 	for(i=0;i<9;i++) 	{ 		printf("%d  ",*(b+i)); 	} 	 	for(i=0;i<9;i++)//对这个二级指针可以进行遍历，为什么？？结果：1 2 3 4 5 6 7 8 9 	{ 		printf("%d  ",*(p+i)); 	} 	return 0; } 问题在代码中，谢谢大神的指教。 看这个样子，应该是把二维数组转换为一维数组顺序输出了，二维数组在内存中实际上也是按顺序排列的 只要获得首个元素的地址，知道元素的类型，完全可以自己解析

user: user-2
content: 引用 22 楼 user-3 的回复:[quote=引用 21 楼 sholber 的回复:] 你觉得我下面的代码有问题么？ char a[3] = {1,2,3,};     int ***** p = (int *****)a;     printf("%d\n", *(char *)(char *****)p);当然有  那个问题就是我之前说过的  脱裤子放屁的 问题  p作为一个 int*****的意义 几乎完全不存在  作为一个 int***** 的p 他做 * 操作 **操作 ++操作 +10操作 这些都丢失了不是吗 [/quote]  你是从哪里看到程序做了 **操作 ++操作 +10操作？有吗？ 臆想是要不得的，只要程序没有语法问题，你就不能说它没有意义。

user: user-3
content: 引用 21 楼 sholber 的回复:你觉得我下面的代码有问题么？ char a[3] = {1,2,3,};     int ***** p = (int *****)a;     printf("%d\n", *(char *)(char *****)p);当然有  那个问题就是我之前说过的  脱裤子放屁的 问题  p作为一个 int*****的意义 几乎完全不存在  作为一个 int***** 的p 他做 * 操作 **操作 ++操作 +10操作 这些都丢失了不是吗

user: user-2
content: 引用 20 楼 user-3 的回复:[quote=引用 19 楼 sholber 的回复:] 胡说什么“做类型转换的过程 原来的指针的意义几乎完全丢失”。 这个指针 除了值以为 所有意义都没有意义 所以我说几乎完全丢失  char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 是不是丢失了 你可以这么看  这里的char** p 换成  char**********************************p int****************** * p void******** p int p long p char **(*p)[132];  是不是结果都一样  p 作为一个char **(*)[132] 的意义是不是几乎完全消失  [/quote]  只要是转换成指针，再转换回来，就没有问题，就不会丧失原来的意义。 你觉得我下面的代码有问题么？ char a[3] = {1,2,3,};     int ***** p = (int *****)a;     printf("%d\n", *(char *)(char *****)p);

user: user-3
content: 引用 19 楼 sholber 的回复:胡说什么“做类型转换的过程 原来的指针的意义几乎完全丢失”。 这个指针 除了值以为 所有意义都没有意义 所以我说几乎完全丢失  char a[3][3] = {1,2,3,4,5,6,7,8,9};     char *b = (char*)a;     char **p = (char**)a;     int i,j;     for(i=0;i<9;i++)         {        printf("%d  ",*(b+i));    }     for(i=0;i<9;i++)         {        printf("%d  ",*((char *)p+i));    }     return 0; 是不是丢失了 你可以这么看  这里的char** p 换成  char**********************************p int****************** * p void******** p int p long p char **(*p)[132];  是不是结果都一样  p 作为一个char **(*)[132] 的意义是不是几乎完全消失

user: user-2
content: 引用 18 楼 user-3 的回复:[quote=引用 16 楼 sholber 的回复:] 他的代码只有一个小小的问题，不是大问题。一个类型转换就解决了。  糙点的说法是 脱裤子放屁 做类型转换的过程 原来的指针的意义几乎完全丢失 [/quote] 麻烦你有点常识，不要信口开河，胡说什么“做类型转换的过程 原来的指针的意义几乎完全丢失”。C标准说得很清楚：  1，除非做为sizeof和一元&运算符的操作数，数组名将被转换为指向其首元素的指针；  2，一个指向对象类型的指针可以转换为指向另一种不同的对象类型的指针，……，转换回来后，结果和原先的指针相等；  3，一个指向任何对象类型的指针可以转换为void指针并转换回来，结果和原始指针相等。