C 中两种不同的指针语法,哪一个是正确的,两者之间有什么区别?
Two different pointer syntax in C which one is right and what's the difference between the two?
我理解指针的概念,我们在函数中使用它们来优化我们使用的space。
我没有得到的是在函数中使用它们时的语法。
示例 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);
逐字基于 OP post:
示例 1 *a=+1;
将指针引用的位置存储的值设置为 +1
。
示例 2 a=+1
使指针指向内存地址 1(这可能无效)。
如果OP表示a += 1
:
示例 1 递增存储在指针引用的位置的值(因为 *
是取消引用运算符)。
示例 2 递增指针本身,使其指向不同的位置,增量是指针类型的大小(如果有数组则方便)。
如果你有int *p
,那么*p
就是指向的值,一个int
。 *p += 1
递增 int
。另一方面,p
本身就是指针int *
。 p += 1
递增指针,使其指向它指向的数组的下一个元素。
这应该打印 10 20 35
:
#include <stdio.h>
void foo(int *p)
{
p += 1; /* increment the pointer */
*p += 5; /* add to the pointed-to int */
}
int main(void)
{
int a[3] = {10, 20, 30};
foo(&a[1]); /* address of / pointer to a[1] */
printf("%d %d %d\n", a[0], a[1], a[2]);
}
这里,
struct node* push(struct node **head, int data)
{
struct node* newnode = malloc(sizeof(struct node));
newnode->data = data;
newnode->next = *head;
return newnode;
}
head
是指向struct node
的指针,所以*head
是指向struct node
的指针。这就是我们通常要存储在链表中的内容,指向下一条数据的指针。 **head
将是一个 struct node
,元素本身,从中赋值将复制数据。
I understand the concept of pointers and that we use them in functions to optimize the space we use.
这不是我们使用它们的原因(至少这不是主要原因,在现代系统中,int *
可能会占用 更多 space比 int
) - 我们使用它们是因为这是向参数写入新值的唯一方法。
请记住,C 语言按值传递所有函数参数 - 对函数中形式参数的任何更改都不会反映在函数调用的参数中。如果你的函数写成
void fun( int a )
{
a += 1;
}
并称为
fun( b );
b
中的值不会受到影响 - a
是一个完全不同的对象,对它的任何更改都不会反映在 b
中。然而,当我们写
void fun( int *a )
{
*a += 1;
}
fun( &b );
我们没有更新 a
的值,我们正在更新 a
指向 的值,在本例中是 b
.
关于链表的例子,它的写法并不要求head
是一个struct node **
,因为它没有得到一个新的指针值写入它;你需要将其命名为
list = push( &list, new_value );
正确更新列表指针。
如果您想更新 head
参数,您只需将 head
作为 struct node **
传递,如下所示:
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 );
等等
我理解指针的概念,我们在函数中使用它们来优化我们使用的space。
我没有得到的是在函数中使用它们时的语法。
示例 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);
逐字基于 OP post:
示例 1 *a=+1;
将指针引用的位置存储的值设置为 +1
。
示例 2 a=+1
使指针指向内存地址 1(这可能无效)。
如果OP表示a += 1
:
示例 1 递增存储在指针引用的位置的值(因为 *
是取消引用运算符)。
示例 2 递增指针本身,使其指向不同的位置,增量是指针类型的大小(如果有数组则方便)。
如果你有int *p
,那么*p
就是指向的值,一个int
。 *p += 1
递增 int
。另一方面,p
本身就是指针int *
。 p += 1
递增指针,使其指向它指向的数组的下一个元素。
这应该打印 10 20 35
:
#include <stdio.h>
void foo(int *p)
{
p += 1; /* increment the pointer */
*p += 5; /* add to the pointed-to int */
}
int main(void)
{
int a[3] = {10, 20, 30};
foo(&a[1]); /* address of / pointer to a[1] */
printf("%d %d %d\n", a[0], a[1], a[2]);
}
这里,
struct node* push(struct node **head, int data)
{
struct node* newnode = malloc(sizeof(struct node));
newnode->data = data;
newnode->next = *head;
return newnode;
}
head
是指向struct node
的指针,所以*head
是指向struct node
的指针。这就是我们通常要存储在链表中的内容,指向下一条数据的指针。 **head
将是一个 struct node
,元素本身,从中赋值将复制数据。
I understand the concept of pointers and that we use them in functions to optimize the space we use.
这不是我们使用它们的原因(至少这不是主要原因,在现代系统中,int *
可能会占用 更多 space比 int
) - 我们使用它们是因为这是向参数写入新值的唯一方法。
请记住,C 语言按值传递所有函数参数 - 对函数中形式参数的任何更改都不会反映在函数调用的参数中。如果你的函数写成
void fun( int a )
{
a += 1;
}
并称为
fun( b );
b
中的值不会受到影响 - a
是一个完全不同的对象,对它的任何更改都不会反映在 b
中。然而,当我们写
void fun( int *a )
{
*a += 1;
}
fun( &b );
我们没有更新 a
的值,我们正在更新 a
指向 的值,在本例中是 b
.
关于链表的例子,它的写法并不要求head
是一个struct node **
,因为它没有得到一个新的指针值写入它;你需要将其命名为
list = push( &list, new_value );
正确更新列表指针。
如果您想更新 head
参数,您只需将 head
作为 struct node **
传递,如下所示:
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 );
等等