指针中(星号)的确切用途是什么?

What exactly is the purpose of the (asterisk) in pointers?

我是编程新手,我正在努力思考 'pointers' 的想法。


int main()
{
    int x = 5;
    int *pointerToInteger = & x;
    cout<<pointerToInteger;

}

为什么当我 cout << pointerToInteger; 时输出是十六进制值,但是当我使用 cout << *pointerToInteger; 时输出是 5 ( x=5)。

* 根据上下文有不同的含义。

  1. 指针声明

    int* ap;  // It defines ap to be a pointer to an int.
    
    void foo(int* p); // Declares function foo.
                      // foo expects a pointer to an int as an argument.
    
  2. 取消引用表达式中的指针。

    int i = 0;
    int* ap = &i;   // ap points to i
    *ap = 10;       // Indirectly sets the value of i to 10
    
  3. 一个乘法运算符。

    int i = 10*20; // Needs no explanation.
    

如果你声明了某个类型的变量,那么你也可以声明另一个指向它的变量。

例如:

int a;

int* b = &a;

所以本质上,对于每一种基本类型,我们也都有对应的指针类型。

例如:shortshort*.

"look at" 变量 b 有两种方法(这可能是大多数初学者感到困惑的地方):

  • 您可以将b视为int*类型的变量。

  • 您可以将*b视为int类型的变量。

    因此,有些人会声明 int* b,而其他人会声明 int *b

    但事实是这两个声明是相同的(space没有意义)。

    您可以使用 b 作为指向整数值的指针,或使用 *b 作为实际指向的整数值。

    可以获取(读取)指向的值:int c = *b.

    你可以设置(写入)指向的值:*b = 5.


指针可以指向任何内存地址,而不仅仅是指向您之前声明的某个变量的地址。但是,在使用指针获取或设置指向内存地址的值时必须小心。

例如:

int* a = (int*)0x8000000;

这里,我们有变量a指向内存地址0x8000000。

如果此内存地址未映射到您程序的内存 space 中,那么使用 *a 的任何读取或写入操作很可能会导致您的程序崩溃,原因是内存访问违规。

您可以安全地更改 a 的值,但更改 *a 的值时应非常小心。

一种看待它的方法是 source/code 中的变量,比如

int a=0;

使 'int a' 引用内存中的值 0。如果我们创建一个新变量,这次是一个(可能更小)"int pointer"、int *,并拥有它指向 &a (a 的地址)

int*p_a=&a; //(`p_a` meaning pointer to `a` see Hungarian notation)

Hungarian notation wiki

我们得到 p_a 指向值 &a 是什么。您现在谈论的是 a 地址处的内容,而 *p_a 是指向 &a(a 的地址)处的任何内容的指针。

当您想修改内存中的值而不创建重复容器时,这很有用。

然而,

p_a 本身在内存中有占用空间(可能小于 a 本身),当你 cout<<p_a<<endl; 时,你将写入指针地址,而不是那里的内容。 *p_a 然而将是 &a

p_a 通常小于 a 本身,因为它只是指向内存的指针而不是值本身。那有意义吗?指针向量比值向量更容易管理,但它们在许多方面做同样的事情。

是的,星号 * 在声明指针变量和通过指针变量访问数据时具有不同的含义。例如

int input = 7;
int *i_ptr = &input;/*Here * indicates that i_ptr is a pointer variable 
                     Also address is assigned to i_ptr, not to *iptr*/ 
cout<<*i_ptr;/* now this * is fetch the data from assigned address */
cout<<i_ptr;/*it prints address */
  • 例如,如果您像 int *ptr = 7; 这样声明它是错误的(不是错误),因为指针 ptr 需要有效地址,但您提供了 constant(7)。声明之前没问题,但是当你像 *ptr 那样取消引用它时,它会出现问题,因为它不知道 7 location 处的 data/value 是什么。因此,始终建议为指针变量分配有效地址。例如

    int input = 7; int *i_ptr = &input; cout<<*i_ptr;

  • 例如 char *ptr = "Hello"; => 这里 * 只是告诉编译器 ptr 是一个 pointer variable 不正常的 & Hello 是一个 char array 即有效地址,所以这个语法没问题。现在你可以做

    if(*ptr == 'H') { /*....*/ } else { /*.... */ }