int * i和int ** i之间的区别

25
什么是“int* i”和“int** i”的区别?
“int* i”表示指向整数的指针,“int** i”表示指向指向整数的指针的指针。

57
那您是在寻求一些指点,对吧...;-) - T.J. Crowder
6
间接地... :O) - AnT stands with Russia
12个回答

29

指向整数值的指针

int* i


指向整数值的指针的指针

int** i

(也就是说,在第二种情况下,您需要对整数的值进行两次解引用操作)


18
  • int* ii是指向类型为int的对象的指针
  • int** ii是指向指向类型为int的对象的指针的指针
  • int*** ii是指向指向指向类型为int的对象的指针的指针的指针
  • int**** ii是指向指向指向指向类型为int的对象的指针的指针的指针的指针
  • ...

4
不一定是指变量。在这种情况下,"variable"这个词可能会使意思有些模糊。 - T.J. Crowder
@T.J. Crowder:即使是常量变量也是一个变量。每次创建时它可能会得到不同的值。 - Nathan Fellman
4
@Nathan 不是在 new int 中。这里没有变量。用 "对象" 替换 "变量" 是恰当的。 - Johannes Schaub - litb
如果是 C 而不是 C++,那么 const 值甚至不一定是常量。 - detly
简单地说,对象是一种类型化的存储区域;变量是通过声明对象引入的。变量的名称表示对象,但您可以在不使用变量的情况下创建对象(例如,通过动态分配)。此外,在C++0x中,变量可以是引用或对象,从技术上讲,引用在C++03中并不是变量。 - CB Bailey
显示剩余7条评论

9

int* pi

pi 是指向整数的指针。

int **ppi

ppi 是指向指向整数的指针的指针。

编辑:

你需要阅读一本关于指针的好书。我推荐 《C语言指针》


8
假设您是一位教师,需要给其中一名学生留下笔记。
int 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 */

等等,等等……


4
对于初学者来说,这并没有解释任何东西。 - Joren

7
我认为这不仅适用于opencv。 int *i 声明了一个指向整数的指针。因此,i 存储一个内存地址,并且C语言期望该内存地址中包含一个整数。 int **i 声明了一个指向指针的指针。指向一个整数。因此,i 包含一个地址,并且在那个内存地址上,C语言期望看到另一个指针。然后,第二个内存地址应该保存一个整数。
请注意,虽然您声明了一个指向整数的指针,但实际的整数并没有被分配。因此,可以说 int *i = 23,这意味着“我有一个变量,我希望它指向内存地址23,该地址将包含一个整数。”但是,如果您尝试读取或写入内存地址23,您可能会遇到段错误,因为您的程序不“拥有”该块RAM。 *i = 100 将导致段错误。(解决方案是使用malloc()。或者您可以使其指向现有变量,如 int j = 5; int *i = &j

4

假设你有几个朋友,其中一个人需要给你一些东西(比如宝藏... :-) 假设约翰拥有这个宝藏

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;

如果您无法直接联系Gill,但需要先联系Jake才能与Gill联系。
int john = treasure;
int *gill = &john;
int **jake = &gill;
int you = **jake;

等等……指针只是间接引用。

这是我今晚睡觉前的最后一个故事 :-)


3
我深信一张图片胜过千言万语。看下面这个例子:
// 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 **,因为它是一个指向整数指针的地址。


1

int* i 是一个整数的内存地址
int** 是一个整数内存地址的内存地址


1

int* i; // i 是一个指向整数的指针。它可以保存整数变量的地址。

int** i; // i 是一个指向指向整数的指针的指针。它可以保存整数指针变量的地址。


0
请注意:
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)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接