这是我从讲义中复制的代码块
/* 2D processing */
printf("\n");
for (i=0; i<3; i++)
for (j=0; j<3; j++)
printf("%d ", *(*(ar+i)+j) );
由于ar
是指向地址位置的指针,*(ar+i)
实际上是指ar+i
地址位置的内容,但我不明白它是如何工作的*(ar+i)+j
,就像内容+数字一样。
还有一件事,
(1) char *ptr; ptr = "This is a string";
(2) char *ptr = "This is a string";
当声明和作业分开时,为什么(1)不能是char *ptr; *ptr="this a string"
?
非常感谢你。
答案 0 :(得分:5)
在第一种情况下,ar
很可能是指向指针的指针(声明为int **ar;
),因此*(a + i)
是指针< / strong>或数组,*(*(a + i) + j)
是元素。
在C和C ++中,有一条规则说数组在很多情况下可以隐式“衰减”到指向第一个元素的指针,因此也可能以其他方式声明ar
:
int **ar; // (1) A pointer to a pointer
int *ar[3]; // (2) An array of pointers
int ar[3][3]; // (3) An array of arrays
当ar + i
写入ar
是一个数组时,它会衰减到指向第一个元素的指针(情况2和3),结果是指针的地址(情况2)或者数组的地址(3)。使用解除引用运算符*
然后获取指针或数组元素。
当你添加j
并且元素是一个数组(情况3)时,这个数组在计算加法之前也会衰减到指向它的第一个元素的指针。因此,回顾一下,取决于ar
的定义方式:
ar // (1) a pointer to a pointer,
// (2) a pointer to array,
// (3) an array of array
ar + i // (1) and (2) address of a pointer
// (3) address of array
*(ar + i) // (1) and (2) a pointer
// (3) an array
*(ar + i) + j // address of an integer in any case
*(*(ar + i) + j) // an integer in any case
如果这看起来令人困惑,请不要担心,因为它是。通常,当您使用*(x + i)
时,因为x
是一个指针,这就是我猜测ar
已被声明为int **ar;
的原因。另请注意,在C和C ++中*(x + i)
完全等同于x[i]
或甚至i[x]
。
在第二种情况下,原因是声明是如何用C语言编写的。
char * s = "foo";
应该被理解为
(char *s) = ("foo"); // Not legal C, just to show type declaration and
// initialization
换句话说,*
是s
的类型声明的一部分,而不是应用于s
的操作。
但请注意
char *s, t;
将s
声明为char *
,将t
声明为char
。
类型声明可能是C语法中最强大但最困难的部分,因为声明的部分并不明显。例如
int *(*f)(int *(*g)(int x));
是f
类型的有效声明,而名称g
和x
则无关紧要,可以省略。
int *(*f)(int *(*)(int)); // Same as above
在这种情况下,f
的类型是一个指向函数的指针,该函数接受指向接受int的函数的指针并返回指向int的指针,并返回指向int的指针。
我的猜测是,绝大多数C程序员在解读之前需要先考虑一下:-D
答案 1 :(得分:2)
详细说明一下:
a[b]
始终是*(a+b)
。如果将它与指针算术规则组合(或从那里派生出来),a
和b
中的任何一个都可以是指针,另一个是整数,表示偏移。
使用此规则,您可以将*(*(ar + i) + j)
等表达式转换为*(ar[i] + j)
,然后转换为ar[i][j]
。
唉,你不能告诉我们ar
是什么,但我们可以告诉你:
ar[i][j]
是一个有效的表达式,ar[i]
是一个指针或数组,它已经衰减到此表达式中的指针。ar
。为了使其成立,ar
可以是
type** ar
type (*ar)[]
type ar[][]
type * ar[]
其中type
是每个组件的类型。
这四种选择都有不同的内存布局,但访问方式相同。
指针算术和数组衰减是如何工作的。最好看一本好书或教程。
第二个问题最好是一个单独的问题。
这只是因为C的分配和初始化规则。
您定义指针
type * p;
type * p = <init value>;
但
p = <new value>;
是你如何分配它。
请记住,字符串文字会在其只读内存部分转换为该字符串的地址。
答案 2 :(得分:1)
问题1)*(*(ar+i)+j)=ar[i][j];
这是因为,ar是完整2D阵列的基地址。
并且ar[i]
(或*(ar+i)
)i
从0到no_of_rows-1将包含数组中每行的地址。
然后ar[i][j]
(或*(*(ar+i)+j
)为您提供特定地址的值。
您还应该查看2D(也是3D)数组的内存表示,以获得更多清除。
问题2):
当您说ptr="abc";
字符串"abc"
的地址存储到ptr
时。
答案 3 :(得分:1)
我认为ar
是指向指针的指针。
int **ar;
ar
指的是指向ar
的指针的地址,即指向int
指针的指针。
*ar
指的是地址ar
指向的内容,即指向int
的指针。
*(*ar)
指的是指针指向的地址的内容(ar
点),即int
。
为什么(1)不能成为char * ptr; * ptr =&#34;这是一个字符串&#34;当声明和作业分开时?
请注意,*
在声明中使用时不是间接运算符。它仅在语句中用作一元运算符时才执行间接。