我开始学C了。
现在,根据我的理解,指针用于指向另一个变量的地址,并通过不直接接近它来更改该变量的值。
现在,我有三个问题:
这是对的吗?如果是,为什么我需要它?
还有其他用途吗?
下列代码行之间有什么区别吗

// 1
int x = 10;
int *ptr = &x;
// 2
int x = 10;
int ptr = &x;

最佳答案

指针的值是内存中另一个对象的位置。鉴于第一组声明:

int x = 10;
int *ptr = &x;

在内存中会有如下内容(地址是凭空提取的,并不代表任何真正的平台):
Item        Address           0x00  0x01  0x02  0x03
----        -------           ----  ----  ----  ----
   x        0x08001000        0x00  0x00  0x00  0x0A
 ptr        0x08001004        0x08  0x00  0x10  0x00

x contains the value 10. ptr contains the address of x. Thus, the expressions x and *ptr are equivalent; reading or writing to *ptr is the same as reading or writing to x.

FWIW, the difference between that and

int x = 10;
int ptr = &x;

是将ptr视为整数,而不是指向整数的指针,所以如果您尝试*ptr(一元*的操作数必须是指针类型)这样的操作,编译器会很生气。
那么,为什么是指针?
C中的指针有三个用途:
首先,指针允许我们模拟按引用传递语义。在C语言中,所有函数参数都是按值传递的;这意味着函数的形式参数是内存中与实际参数不同的对象。例如,使用这个swap函数:
void swap(int a, int b)
{
  int t = a;
  a = b;
  b = t;
}

int main(void)
{
  int x = 1, y = 2;
  swap(x, y);
  ...
}

如果我们看一下记忆,我们有如下的东西:
Item        Address           0x00  0x01  0x02  0x03
----        -------           ----  ----  ----  ----
   x        0x08001000        0x00  0x00  0x00  0x01
   y        0x08001004        0x00  0x00  0x00  0x02
   a        0x08001010        0x00  0x00  0x00  0x01
   b        0x08001014        0x00  0x00  0x00  0x02

This means any changes made to a and b are not reflected in x or y; after the call to swap, x and y will remain unchanged.

However, if we pass pointers to x and y to swap, like so:

void swap(int *a, int *b)
{
  int t = *a;
  *a = *b;
  *b = t;
}

int main(void)
{
  int x = 1, y = 2;
  swap(&x, &y);
  ...
}

我们的记忆是这样的:
Item        Address           0x00  0x01  0x02  0x03
----        -------           ----  ----  ----  ----
   x        0x08001000        0x00  0x00  0x00  0x01
   y        0x08001004        0x00  0x00  0x00  0x02
   a        0x08001010        0x08  0x00  0x10  0x00
   b        0x08001014        0x08  0x00  0x10  0x04

a and b contain the addresses of x and y, so reading and writing from the expressions *a and *b are equivalent to reading and writing from x and y. Thus, after this call to swap, the values of x and y will be changed.

The second reason we use pointers is to track dynamically-allocated memory. When we want to create a new object at runtime, we use the malloc or calloc call, which allocates the memory and returns a pointer to it:

int *p = malloc(sizeof *p * N); // dynamically allocates enough memory
                                // to hold N integer values and saves
                                // the location to p

指针是跟踪C中动态分配内存的唯一方法。
最后,指针允许我们创建动态数据结构,如列表、树、队列等。其思想是结构中的每个元素都显式地指向下一个元素。例如,这里有一个定义简单整数列表的类型:
struct elem
{
  int data;
  struct elem *next;
};

struct elem类型的每个对象都显式指向以下struct elem类型的项。这允许我们根据需要向列表中添加项或从列表中删除项(与数组不同),并允许我们在构建列表时对其进行排序(我会发布一个示例,但我非常累,这可能没有意义;无论如何,您很快就会找到它们)。

关于c - C指针的用法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12447192/

10-11 23:16
查看更多