什么是“int* i”和“int** i”的区别?
“int* i”表示指向整数的指针,“int** i”表示指向指向整数的指针的指针。
“int* i”表示指向整数的指针,“int** i”表示指向指向整数的指针的指针。
指向整数值的指针
int* i
指向整数值的指针的指针
int** i
(也就是说,在第二种情况下,您需要对整数的值进行两次解引用操作)
int* i
: i
是指向类型为int
的对象的指针int** i
: i
是指向指向类型为int
的对象的指针的指针int*** i
: i
是指向指向指向类型为int
的对象的指针的指针的指针int**** i
: i
是指向指向指向指向类型为int
的对象的指针的指针的指针的指针new int
中。这里没有变量。用 "对象" 替换 "变量" 是恰当的。 - Johannes Schaub - litbC
而不是 C++
,那么 const
值甚至不一定是常量。 - detlyint note;
好的...我是说整个类
int *class_note; /* class_note[0]: note for Adam; class_note[1]: note for Brian; ... */
好的...不要忘记你有几个类
int **classes_notes; /* classes_notes[0][2]: note for Charles in class 0; ... */
此外,您还在多个机构授课。
int ***intitute_note; /* institute_note[1][1][1]: note for David in class 1 of institute 1 */
等等,等等……
int *i
声明了一个指向整数的指针。因此,i
存储一个内存地址,并且C语言期望该内存地址中包含一个整数。
int **i
声明了一个指向指针的指针。指向一个整数。因此,i
包含一个地址,并且在那个内存地址上,C语言期望看到另一个指针。然后,第二个内存地址应该保存一个整数。int *i = 23
,这意味着“我有一个变量,我希望它指向内存地址23,该地址将包含一个整数。”但是,如果您尝试读取或写入内存地址23,您可能会遇到段错误,因为您的程序不“拥有”该块RAM。 *i = 100
将导致段错误。(解决方案是使用malloc()。或者您可以使其指向现有变量,如 int j = 5; int *i = &j
)假设你有几个朋友,其中一个人需要给你一些东西(比如宝藏... :-) 假设约翰拥有这个宝藏
int treasure = 10000; // in USD, EUR or even better, in SO rep points
int john = treasure;
int you = john;
int john = treasure;
int *gill = &john;
int you = *gill;
int john = treasure;
int *gill = &john;
int **jake = &gill;
int you = **jake;
等等……指针只是间接引用。
这是我今晚睡觉前的最后一个故事 :-)
// Finds the first integer "I" in the sequence of N integers pointed to by "A" .
// If an integer is found, the pointer pointed to by P is set to point to
// that integer.
void f(int N, int *A, int I, int **P) {
for(int i = 0; i < N; i++)
if(A[i] == I) {
// Set the pointer pointed to by P to point to the ith integer.
*P = &A[i];
return;
}
}
因此,在上面的例子中,A
指向包含 N 个整数序列的第一个整数。而 P
则指向调用者将存储找到的整数的指针。
int Is[] = { 1, 2, 3 };
int *P;
f(3, &Is[0], 2, &P);
assert(*P == 2);
&P
用于将 P
的地址传递给函数。这个地址的类型是int **
,因为它是一个指向整数指针的地址。
int* i 是一个整数的内存地址
int** 是一个整数内存地址的内存地址
int* i; // i 是一个指向整数的指针。它可以保存整数变量的地址。
int** i; // i 是一个指向指向整数的指针的指针。它可以保存整数指针变量的地址。
int *i
并非完全可互换
int i[]
这可以看出以下代码将会编译通过:
int *i = new int[5];
虽然这样做不会:
int i[] = new int[5];
其次,您必须为其提供一个构造函数列表:
int i[] = {5,2,1,6,3};
你还可以使用[]形式进行一些检查:
int *i = new int[5];
int *j = &(i[1]);
delete j;
编译无警告,同时:
int i[] = {0,1,2,3,4};
int j[] = {i[1]};
delete j;
会出现以下警告:
警告 C4156:删除数组表达式时未使用“delete”的数组形式;已替换为数组形式 警告 C4154:删除数组表达式时,提供指针转换
这两个示例的最后两个版本都会导致应用程序崩溃,但使用[]声明类型的第二个版本会发出警告,表示你自己会陷入困境。
(Win32控制台C++项目,Visual Studio 2010)