首页 > 解决方案 > C语言中有两种不同的指针语法,哪一种是对的,两者有什么区别?

问题描述

我了解指针的概念,并且我们在函数中使用它们来优化我们使用的空间。
我没有得到的是在函数中使用它们时的语法

示例 1:

void fun(int * a)//that means we declared a pointer to an integer type a
{
  *a+=1; 
}
fun(&b);//calling the function for int b=10;

示例 2:

void fun(int * a)//that means we declared a pointer to an integer type a
{
  a+=1;
}
fun(&b);//calling the function for int b=10;

问题:哪一个是正确的,如果他们都是正确的,两者之间有什么区别?

编辑在 AKX 的回答之后: 为什么我们在链表中这样做呢?如果我们想改变对象的值而不是指针的地址(在这种情况下是双指针),它不应该是 **head 而不是 *head 吗?

void push(struct node **head, int data)
{
        struct node* newnode = malloc(sizeof(struct node));
        newnode->data = data;
        newnode->next = *head;
}

push(&head,1);

标签: cpointerslinked-listdouble-pointer

解决方案


我了解指针的概念,并且我们在函数中使用它们来优化我们使用的空间。

这不是我们使用它们的原因(至少这不是主要原因,并且在现代系统上int *可能会比 占用更多空间int) - 我们使用它们是因为这是向参数写入新值的唯一方法。

请记住,C 通过值传递所有函数参数 - 函数中形式参数的任何更改都不会反映在函数调用中的参数中。如果你的函数写成

void fun( int a )
{
  a += 1;
}

并称为

fun( b );

in 的值b不会受到影响 -a是一个完全不同的对象,对它的任何更改都不会反映在b. 然而,当我们写

void fun( int *a )
{
  *a += 1;
}

fun( &b );

我们没有更新 的值a,我们正在更新事物a 指向的值,在这种情况下是b

关于链表示例,它的编写方式不需要head是 a struct node **,因为它没有将新的指针值写入其中;你需要把它称为

list = push( &list, new_value );

正确更新列表指针。

如果你想更新参数,你只需要传递,head就像这样:struct node **head

void push( struct node **head, int data )
{
  struct node *n = malloc( sizeof *n );
  if ( n )
  {
    n->data = data;
    n->next = *head;  // n->next points to the old head of the list
    *head = n;        // n becomes the new head of the list
  }
}
    

并将其称为

struct node *list = NULL;  // list is initially empty

push( &list, 42 );
push( &list, 300 );

等等


推荐阅读