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

时间:2012-12-07 03:53:13

标签: c pointers

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

这就是为什么:我不理解命名!或者应用程序,实际上是指针。在阅读了几本“你想要学习的东西”之后。书籍和文章,我一次又一次遇到类似的代码:"如何创建和实例化指针"。

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

以下是代码:

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

或者,或许更令人困惑:

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

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

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

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

取这段代码,例如:

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

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

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

或者这个块:

char *sp;
sp = "Hello";
printf("%s",sp);
我认为指针指向一个地址。 "你好"不是一个地址。

考虑到前两个块,请看看最后一个块:

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

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

2 个答案:

答案 0 :(得分:2)

  

请注意chptr的命名方式不同 - 此时我添加了一个   回答 - 来自其他两个变量,名为ch。为什么不命名   所有三个变量ch?

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

此外,在第一个代码块中,我们有...... * chptr =& ch ;;在里面   第二,chptr =& ch;。是什么让它可以放弃   第二个区块中的星号?

  • 使用'*'声明指针变量的语法,例如:int *pInt;
  • 为指针变量赋值(使其指向某个东西),你不需要'*'。例如:

        int *pInt;
        pInt = &someInt;
    
  • 但是,要为指针变量指向的地址赋值或者获取变量指向的值,必须使用'*'

    取消引用它
        int *pInt;
        int someInt = 100;
        pInt = &someInt;
        *pInt = 50;
        printf("%d - %d", *pInt, someInt); // prints "50 - 50"
    
  

接下来,我想知道指针的应用是什么。

  • 指针用于:

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

为什么将name声明为指向不具有的名称变量的指针   存在,以及为什么在不使用的情况下将age变量声明为int   指针?

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

  • “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仍具有价值{ {1}})。

    • 5可能不是您的意图。它可能会导致错误,因为&p = 7将产生一个值,并且为值赋值是非法的(例如:它将评估为这样的值:&p

      < / LI>
    • 考虑上述变量的以下内存样本

      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;

答案 1 :(得分:1)

Example code:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    long j;
    int *p;

    i = 5;
    p = &i;  ---> Assigning address of "i" to p, so that pointer p points to "i"
                  By dereferencing pointer "p" i.e. by *p, shall retrieve value "5". 

    j = *p; or j = i (alternative to assign value "5" to "j")

    printf("Value of j:%d \n", j); --> Output is "5".

    &p = 7; //i = 7? --> will not change the value of "i" to 7, but instead  
                         will try to change the address of "p", which cannot be 
                         modified.                              

    j = (long)&i;  ---> Assigns address of "i" i.e "100" to "j". 

    printf("Value of j:%p \n", j); --> Output is address of "i" i.e. "100"

    printf("Value of i:%d \n", i); --> Output is "5". Value assigned to "i".

    printf("Address of i:%p \n", &i); --> Output is "100" i.e. address of "i" in our
                                          case.

    printf("Value of *p:%d \n", *p); --> Output is "5". Since pointer p is pointing 
                                        to "i" i.e. "100" in our case. 
                                        *p -> by dereferencing, retrieves value 
                                        present at the address "100" 
                                        that would be "5".

    printf("Value of p:%p \n", p); --> Output is "100". Pointer p is pointing 
                                       to "i" i.e. "p = &i" it will be "100" in our 
                                       case.   

    printf("Address of p:%p \n", &p); --> Output would be the address of pointer "p".
                                          It will not be same as the address of "&i" 
                                          or value present in "p".

    return 0;       
}