使用或指向指针的指针(C)

时间:2015-09-05 17:29:48

标签: c pointers

我理解指针是什么,但我很难理解它们的用途。我可以想到你可以使用指针的情况,但我能想到的这些情况也可以用不同的方式解决,而不需要做太多的工作。无论如何,我真正不理解的是使用指针指针。例如,我遇到了这个简单的C代码:

#include <stdlib.h>

int main(int argc, char** argv)
{
    ...
}

根据我的理解,这是一个程序,可以通过命令行调用无限参数,并且是一种惯例。 char ** argv的目的究竟是什么?为什么在这里使用指向char的指针?如果这是一个微不足道的问题,我很抱歉,但我似乎很难在这里大局。

提前谢谢你, Sparkas

3 个答案:

答案 0 :(得分:3)

指向指针(指针...)的指针在需要多个间接层的所有情况下都很有用。

char** args的特定情况下,你有一个字符串数组作为参数,C中的每个字符串都是char*所以基本上你有一些像

char** args
        |
         ->  | char* | char* | char* | char* |
                 |       |
                 v       |
                |f|o|o|  |
                         |
                         v
                        |b|a|r|

这有什么奇怪的?考虑一下T*定义一个类型,它是指向T的指针。现在,如果T == char* char**,则char*定义指向char的指针,而from myapp.tasks import add 指针指向if(isset($json['results'][0])) { $lat = $json['results'][0]['geometry']['location']['lat']; //-6.2087634 $lng = $json['results'][0]['geometry']['location']['lng']; //106.845599 }

请记住,在C和C ++中,指针可以表示数组。

答案 1 :(得分:1)

有一些C的例子,其中argv被交替声明为指针数组:

char *argv[]

指向指针语法的指针:

char **argv

声明指向可能是指针数组中第一个指针的指针。另一个常见用法是将指针传递给指向链表的指针:

node *head; /* pointer to linked list */
/* ... */
/* pass a pointer to head */
list_function(&head);
/* ... */
/* use and update head */
list_function(node **head){ ... }

答案 2 :(得分:1)

指针的指针出现在很多情况下。可能最常见的是当你需要一个函数来写一个指针参数时。

请考虑以下事项:

void foo( T *p ) // for any type T
{
  *p = new_value(); // write to the thing p points to
}

void bar( void )
{
  T var;
  foo( &var ); // foo updates value of var
  ...
}

此处函数foo正在通过指针var更新bar中定义的变量p

现在让我们用指针类型T替换类型Q *

void foo( Q **p )
{
  *p = new_pointer_value(); // write to the thing p points to
}

void bar( void )
{
  Q *var;
  foo( &var );  // foo updates the value of var
  ...
}

语义完全相同;我们正在为var写一个新值。唯一的区别是var有一个指针类型,所以我们需要在foo中使用多个间接层。

第二种常见情况是当你有一个指针数组,并将该数组传递给另一个函数。例如:

void foo( char **s )
{
  while ( *s )
    puts( *s++ );
}

void bar( void )
{
  char *strings[] = { "blurga", "bletch", "blah", NULL };
  foo( strings );
}

strings是指向char的指针数组;数组的每个元素都是字符串文字(或NULL)的地址。在对foo的调用中,数组表达式strings被转换(“衰减”)为“指向char的指针”类型的表达式,表达式的值是地址strings数组 1 的第一个元素。由于数组的第一个元素是指针,因此第一个元素的地址是指向指针的指针。

第三种情况是你为2D数组分配内存:

T **arr = malloc( sizeof *arr * rows );
if ( arr )
{
  for( size_t i = 0; i < rows; i++ )
  {
    arr[i] = malloc( sizeof *arr[i] * cols );
  }
}

<小时/> 1。除非它是sizeof或一元&运算符的操作数,或者是用于初始化声明中的另一个数组的字符串文字,否则类型为“N”的表达式 -element数组T“将被转换(”衰减“)到类型为”T指针“的表达式,表达式的值将是数组的第一个元素的地址。