请解释一下这背后的概念,(c编程中的ptr和*ptr)的区别 [已关闭]

Please Explain the concept behind this, difference between (ptr and *ptr in c programming) [closed]

提问人:realwixi 提问时间:11/11/2023 最后编辑:Jerry Strattonrealwixi 更新时间:11/11/2023 访问量:82

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

10天前关闭。

#include <stdio.h>

struct Student {
    int id;
    char name[20];
};
    
int main() {
    struct Student stu;  
    struct Student *ptr = &stu;  
        
    ptr->id = 101;
    strcpy(ptr->name, "John Doe");
            
    printf("Student ID: %d\n", ptr->id);
    printf("Student Name: %s\n", ptr->name);
    
    // explain the below code 
    printf("%d\n", (void *)ptr);
    printf("%d\n", &stu);
    printf("%d\n", *ptr);
    
    return 0;
}

解释指针部分,我已评论的代码。 并且还做了解释:我很困惑为什么并且有相同的记忆。(void*)ptr*ptr

C 指针 变量

评论

1赞 Some programmer dude 11/11/2023
拿出一支笔和一些纸。在纸上画两个框,标记一个,另一个。从 到 画一个箭头。这基本上就是指针的工作方式。当你这样做时,你从盒子开始,然后按照箭头到它所指向的盒子,得到对象。stuptrptrstu*ptrptrstu
0赞 T.J. Crowder 11/11/2023
想必反斜杠不在您的真实代码中?struct Student\* ptr = &stu;
1赞 Some programmer dude 11/11/2023
请注意,要打印指针,应使用需要参数的格式(如果参数不正确,则必须强制转换参数)。格式为 。格式说明符和参数类型不匹配会导致未定义的行为printf%pvoid *%dint
0赞 Some programmer dude 11/11/2023
从上面关于 的注释中,知道它与结构对象相同,那么很容易理解使用打印 a 是行不通的。事实上,如果你的编译器没有抱怨它,那么你需要在构建时启用更多的警告。printf*ptrstu%dstruct Student

答:

2赞 Mureinik 11/11/2023 #1

ptr是引用结构的指针。stu

&是“地址”运算符。的地址与指向的指针相同。stuptr

*是间接(“对象指向者”)运算符。 事实上.如您所见,从技术上讲,您可以将其打印为整数,但这样做意义不大。它不会(或至少不应该)打印与 相同的值。例如,参见:https://onlinegdb.com/3DmUu2ftv*ptrstu%dptr

0赞 chqrlie 11/11/2023 #2

ptr是指向 a 的指针,并且是 的地址,它们都具有与您初始化的值相同的值,因此打印 和 的值应该产生相同的输出,但发布的代码具有未定义的行为:Student struct&stuStudent structptr = &stuptr&stu

  • printf("%d\n", (void *)ptr) %d期望 一个 ,而不是一个 ,这具有未定义的行为。请改用以下命令:intvoid *

    printf("%p\n", (void *)ptr);
    
  • printf("%d\n", &stu)同样的话。请改用以下命令:

    printf("%p\n", (void *)&stu);
    
  • printf("%d\n", *ptr)在传递 by 值时具有未定义的行为,该值无法处理,并且它需要 .没有可移植的方法可以直接打印结构,您必须单独打印其成员。struct Studentprintfint

*ptr是 所指向的结构本身。str

0赞 Lajos Arpad 11/11/2023 #3

当你指向某物时,你的手指(参考)和你所指向的事物之间是有区别的。 是“手指”,是它所指向的东西。ptr*ptr

ptr是。&stu

*ptr是。stu

所以,与。 是“手指”与“东西”。除非您声明指针,也就是说,当您拥有以下内容时:ptr*ptr

struct Student *ptr = &stu; 

在这种特定情况下,只是指定 将是 ,也就是说,在上面,是类型规范的一部分。*ptrptrstruct Student **

0赞 John Bode 11/11/2023 #4

下线后

struct Student *ptr = &stu;

以下关系为真:

 ptr == &stu // struct Student * == struct Student *
*ptr ==  stu // struct Student   == struct Student

表达式 and 计算结果为变量的地址。这两行正在尝试打印该地址值:ptr&stustu

printf("%d\n", (void *)ptr);
printf("%d\n", &stu);

但他们弄错了;打印指针值的正确方法是使用转换说明符并将表达式转换为:pvoid *

printf( "%p\n", (void *) ptr );
printf( "%p\n", (void *) &stu );

强制转换 - 它的意思是“将以下表达式视为具有指向 ”的类型指针。转换说明符期望其对应的参数具有类型。通常,您不需要显式地将指针值转换为 ,但由于 参数的处理方式,您需要在此处进行。(void *)voidpvoid *void *printf

表达式和计算变量本身; 充当变量的某种别名,但不是真正的别名。*ptrstustu*ptrstu

这一行:

printf("%d\n", *ptr);

简直是大错特错。转换说明符期望其对应的参数具有 type ,但表达式具有 type 。代码的原始作者所指望的是,由于 struct () 的第一个成员是一个整数,因此此代码将打印该整数值。dint*ptrstruct Studentid

在实践中,它有时会该行为是未定义的,这意味着编译器不需要以任何特定方式处理它,并且您不应期望任何特定结果。该行写成

printf( "%d\n", ptr->id );