c - *、&、...解释指针、变量和地址的关系和命名,使用以下代码块:

标签 c pointers

我最近正在审阅一篇关于指针的优秀且备受好评的文章:What are the barriers to understanding pointers and what can be done to overcome them?当我通读它时,我开始理解指针是什么。不幸的是,我仍然无法使用它们。

原因如下:我不明白命名!或者实际上是指针的应用。在阅读了几本“so-you-want-to-learn-c”书籍和文章后,我一次又一次地遇到类似的代码:“如何创建和实例化指针”。

回答时,请使用示例代码来演示指针实际输出的内容。

代码如下:

char ch = 'c'; 
char *chptr = &ch;

或者,也许更令人困惑:

char ch = 'c';
char *chptr;
chptr = &ch;

请注意chptr与其他两个变量的命名不同,这两个变量的名称为 ch 。为什么不将所有三个变量命名为 ch ?为指针指定不同的名称可以解决什么问题?

此外,在第一段代码中我们有 ...*chptr = &ch; ;第二个,chptr = &ch; 。是什么使得在第二个 block 中删除星号是可以接受的?

接下来我想知道指针的应用是什么。我是否总是需要一个指针(什么时候需要,什么时候不需要)?提交答案后,我有信心——相信我将能够理解使用指针的更复杂的代码——足以继续直观地调整语言。但我仍然充满好奇。

以这段代码为例:

typdef struct person
{
  char *name;
  int age;
}

为什么将 name 声明为指向不存在的 name 变量的指针,为什么将age变量声明为 int 而不使用指针?由于这个 block ,这是没有意义的:

int main()
{
/* below, the int is a pointer */
  int *p;
  void *up;
  return 0;
}

或者这个 block :

char *sp;
sp = "Hello";
printf("%s",sp);

我以为指针指向一个地址。 “你好”不是地址。

记住前面的两个 block ,看看最后一个 block :

int main()
{
  int i,j;
  int *p;
  i = 5;
  p = &i;
  j = *p; //j = i?
  &p = 7; //i = 7?
}

j 不应该设置为 &i 因为 *p = &i不是i 。并且不应该&p = 7将p的地址设置为7,这可能不是i?

最佳答案

Notice that chptr is differently named--at this point I added an answer--from the other two variables, which are named ch. Why not name all three variables ch?

  • 通常的做法是,指针以“p”为前缀(或者在本例中以“ptr”为后缀),以便代码阅读器清楚该变量是一个指针。正如您现在所知,使用指针进行编程一开始很困难,虽然 int *i = 1;int i = 1 都是合法的,但无意中将其中一个替换为另一个可能会导致一些严重的调试时间。

Also, in the first block of code we have ...*chptr = &ch;; in the second, chptr = &ch;. What is making it acceptable to drop the asterisk in the second block?

  • 这是使用“*”声明指针变量的语法,例如:int *pInt;
  • 要给指针变量赋值(使其指向某个对象),不需要“*”。例如:

        int *pInt;
        pInt = &someInt;
    
  • 但是,要为指针变量指向的地址赋值或获取变量所指向的值,则必须使用“*”取消引用它

        int *pInt;
        int someInt = 100;
        pInt = &someInt;
        *pInt = 50;
        printf("%d - %d", *pInt, someInt); // prints "50 - 50"
    

Next, I wonder what the applications of pointers are.

  • 指针的用途包括:

    1. 按值传递给函数
    2. 动态内存分配 ...

Why declare the name as a pointer to a name variable that doesn't exist, and why declare the age variable as an int without using pointers?

  • “Hello”是一个包含 5 个字符的数组。使用sp = "Hello",“Hello”被存储在内存位置,并且它的地址被分配给sp
  • 从您的示例中,我假设名称可以包含任意数量的字符,因此在程序执行期间,将使用动态分配来存储名称。

I thought pointers pointed to an address. "Hello" isn't an address.

  • “Hello”(C 中的字符串)被视为字符数组。在本例中,sp指向包含5个字符的数组的内存位置(堆或堆栈),当您在赋值中使用它时,它将返回“Hello”字符串在内存中的地址。

    int main()
    {
      int i,j;
      int *p;
      i = 5;
      p = &i;
      j = *p; //j = i?
      &p = 7; //i = 7?
    }
    
    • j 不是 i,因为更改 j=100 不会影响 i 的值(i 仍然具有值 5)。

    • &p = 7 可能不是您想要的。它可能会导致错误,因为 &p 将产生一个值,并且将一个值分配给一个值是非法的(例如:它将计算为如下所示:0x0108 = 7;)

    • 考虑上述变量的以下内存示例

       address | var    | value
       0x0100  | i      | undefined
       0x0104  | j      | undefined
       0x0108  | p      | undefined
      
    • j = *p之后,

       0x0100 | i      | 5
       0x0104 | j      | 5
       0x0108 | p      | 0x0100
      

*p=7 之后(根据 &p = 7; 更正)

         0x0100 | i      | 7
         0x0104 | j      | 5
         0x0108 | p      | 0x0100

关于c - *、&、...解释指针、变量和地址的关系和命名,使用以下代码块:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13756635/

相关文章:

c - 对于数组,为什么 a[5] == 5[a]?

c++ - 指针弄乱数组元素的地址

c - 为什么我不能将赋值分解为两个不同的语句?

c - 在没有新线程的情况下替换无限循环

c++ - 在 C++ 中进行数学运算时,浮点错误如何传播?

c++ - 递归函数中的 GOTO 指令

c - 如何在C中使用指针类型?

c++ - 子级访问同一父级的其他子级的元素

c - 当我尝试在函数中添加节点但在主函数中工作时,为什么我的程序崩溃了

c - 错误 : expected expression before ‘float’