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

Posted

技术标签:

【中文标题】指针中(星号)的确切用途是啥?【英文标题】:What exactly is the purpose of the (asterisk) in pointers?指针中(星号)的确切用途是什么? 【发布时间】:2016-08-26 01:12:44 【问题描述】:

我是编程新手,我正试图围绕“指针”这个概念展开思考。


int main()

    int x = 5;
    int *pointerToInteger = & x;
    cout<<pointerToInteger;


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

【问题讨论】:

一个是指针(即内存地址)——这是十六进制值。另一个是那个地址的内容。 * 在指针前面的意思是“取消引用”指针,或者遍历它。 * 在类型之后指示指向该类型的指针。指针只是指向内存中存储给定信息的某个位置的方向。 cout &lt;&lt; pointerToInteger打印pointerToInteger指向的地址; cout &lt;&lt; *pointerToInteger 打印存储在该地址的内容。可以这样想:pointerToInteger是你家门前的邮箱; *pointerToInteger 是那个邮箱里面的东西。 【参考方案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.
    

    取消引用表达式中的指针。

    int i = 0;
    int* ap = &i;   // ap points to i
    *ap = 10;       // Indirectly sets the value of i to 10
    

    乘法运算符。

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

【讨论】:

int* apint *ap 有区别吗(风格除外)? @c.berger,不,没有。【参考方案2】:

查看它的一种方法是,您的源代码/代码中的变量,比如

int a=0;

让'int a'指向内存中的一个值,0。如果我们创建一个新变量,这次是一个(可能更小的)“int指针”int *,并让它指向&a(地址一)

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

Hungarian notation wiki

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

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

p_a 本身在内存中有一个占用空间(可能小于a 本身),当您使用cout&lt;&lt;p_a&lt;&lt;endl; 时,您将写入指针地址的任何内容,而不是那里的内容。 *p_a 但是将是 &amp;a

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

【讨论】:

【参考方案3】:

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

例如:

int a;

int* b = &amp;a;

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

例如:shortshort*

有两种方法可以“查看”变量b(这可能会让大多数初学者感到困惑):

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

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

因此,有些人会声明int* b,而另一些人会声明int *b

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

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

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

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


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

例如:

int* a = (int*)0x8000000;

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

如果此内存地址未映射到程序的内存空间中,那么使用*a 的任何读取或写入操作很可能会由于内存访问冲突而导致您的程序崩溃。

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

【讨论】:

【参考方案4】:

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

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 那样取消引用它时,它会出现问题,因为它不知道data/value7 location 是什么。因此,始终建议为指针变量分配有效地址。例如

int input = 7; int *i_ptr = &amp;input; cout&lt;&lt;*i_ptr;

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

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

【讨论】:

以上是关于指针中(星号)的确切用途是啥?的主要内容,如果未能解决你的问题,请参考以下文章

“*”在各种指针场景中是啥意思?

使用 pip 安装 python 包时星号 * 的用途是啥

微处理器中使用的堆栈指针是啥?

不带星号的函数指针参数

数据库中常见的“索引”是啥意思?有啥用途?

指针初学