指针初始化之间的差异

时间:2009-08-14 00:14:42

标签: c pointers

我在Standard,K& R C中发言。

假设:

const char a[] = {1, 2, 3};
const char *p = NULL;

这两个陈述是否相同:

  1. *p = a;

  2. p = a;

  3. 他们每个人都会在片段的第三行。

    1和2肯定看起来不一样。

    两者之间的区别是什么?

7 个答案:

答案 0 :(得分:4)

没有

p = a初始化指针指向别的东西(通常它会复制另一个指针,或者你会指向一个引用,ala p = &a

*p = a初始化p指的是什么。你是“解除引用”(看)p指向的东西。如果p在您的示例中指向NULL,则会崩溃(这很好!您不想意外访问某些内容并弄乱您的程序)。

在这种情况下,p = a将指向数组a []的第一个,*p = a将尝试更改数组的第一个(它将无效;您已将其声明常数)。

这是C ++中的一个小示例程序,其语法与C语言几乎完全相同。

#include <iostream>

int main()
{
    char arr[5] { 'a', 'b', 'c' }; // arr[3] and arr[4] are set to 0
    char *ptr = arr; //point to 'a'

    for (int i = 0; i != 5; i++)
    {
       *ptr = 'f'; //this changes the array
       ptr++; //this changes what the pointer points to; moves it to next in array
    }

    for (int i = 0; i != 5; i++)
    {
        std::cout << *ptr << " ";
    }

    //outputs f f f f f
}

答案 1 :(得分:2)

*运算符就是我们所说的dereference operator。要了解它的作用,你必须准确理解指针是什么。

当你这样做时

char *p;

“变量”p不使用与普通char相同的内存量,它使用更多内存:它使用正确识别计算机内存位置所需的内存量。所以,假设您使用的是32位架构,变量p占用4个字节(不是您期望从char中获得的1个字节)。

所以,当你这样做时

p = a;

你清楚地看到你正在改变变量p的内容,也就是说,你在其中放入另一个32位数字:你正在改变它所指向的地址。

执行该行后,p的值是字符数组a的内存地址。

现在为取消引用运算符。当你这样做

*p = 'Z';

您告诉编译器您要将值'Z'存储在p指向的地址上。因此,p的值在此行之后保持不变:它继续指向相同的地址。 此地址的值已更改,现在包含“Z”。

所以,

的最终效果
char a[] = {'a', 'b', 'c'};
char p = a;
*p = 'Z';

与将数组a的第一个位置更改为“Z”相同,即:

char a[] = {'a', 'b', 'c'};
a[0] = 'Z';

注意:使指针指向数组时有区别:包含数组的变量只包含第一个元素的地址,因此 a 是与“数组的起始地址”相同。

通常你会看到&amp;运营商。它是一个用于获取变量的内存地址的运算符。例如:

int number = 42;
int pointer = &number;
printf("%d", *pointer);

我们拥有所有这些。第一行创建一个整数变量并在其中存储42个。

第二行创建一个指向整数的指针,并在其中存储 变量编号的地址。

第三行重新指针指向的地址上的值。

因此,诀窍是将* x指向x 指向的地址为,将&x;读为 x 的地址。

答案 2 :(得分:1)

第一个取消引用空指针,并尝试为其分配数组的地址。这将是编译器错误,因为char != char []。如果不是,它可能会崩溃。

第二个设置p以指向数组。

答案 3 :(得分:1)

这是我学习C时使用的技巧(现在仍在使用)。

每当您在代码中看到变量前面的*时,会自动将其读作“指向的内容”。

因此,您应该能够轻松地看到将“p”设置为“a”与将“p指向的内容”设置为“a”非常不同。

此外,由于p应该指向一个char,设置char p指向(当前内存位置为0的“char”,假设null为0)到char指针(a)可能会失败在编译时,如果你很幸运(取决于你的编译器和lint设置,它可能实际上成功。)

来自注释的

:在像f(char c)这样的函数声明中,我通常会尝试将变量名与其余部分分开 - 所以它将是f((char )c )。所以c是char *。完全像变量定义。

另外&amp;通常读作“地址”,但这种情况会更加明显。我自己读书的几个例子。可能会或可能不会帮助你。

int a[] = {1,2,3}; // I mentally parse this as (int[]) a, so a is an int array.
int *p;            // p is a pointer to "integers"
int i;
p=a;               // p acts exactly as a does now. 

i=*p;          // i is "What is pointed to by" p (1)
i=p;           // i is some memory address
i=*a;          // i is what is pointed to by a (1)
i=p[1];        // Don't forget that * and [] syntax are generally interchangable.
i=a+1;         // Same as above (2).
p=&i;          // p is the address of i (it can because it's a pointer)
               // remember from hs algebra that = generally reads as "is", still works!
*p=7;          // what is pointed to by p (i) is 7;
a=*i;          // whoops, can't assign an array.  This is the only difference between
               // arrays and pointers that you will have to deal with often, so feel
               // free to use which ever one you are more comfortable with.

char c='a';
char *  d = &c;// d is a char pointer, and it is the address of c
char ** e ;    // e is a pointer to a memory location containing
               // a pointer to a char!
e=&d;          // gets d's address. a pointer to a pointer gets
               // the address of a pointer.  Messy but gets the job done

**e=5;         // what is pointed to by what is pointed to by e is 5.
*e=&'f';       // what is pointed to by e (which is a char * itself, and is still d!)
               // is set to the address of the memory location holding the value 'f'.
               // does not change c or e, just d! 

我在10年内没有接触过c,所以有些可能有点不对劲,但这有助于我大声读出来。

答案 4 :(得分:1)

我认为你错了:

char a[8];
char *p=a;

这是合法的,并且与:

相同
char a[8];
char *p=NULL;
p=a;

使用:

char a[8];
char *p=NULL;
*p=a;

正如其他人所说的会产生编译错误或分段错误。

 In the left side of declarations you should read *x as pointer(x) while in
 statements it must be read as value_pointed_by(x). &x on the other hand
 would be pointer_to(x)

答案 5 :(得分:0)

不,它们不等同

如果p = NULL,那么执行*p = a会给您一个细分错误。

答案 6 :(得分:0)

  1. 因为“* p”取消引用指针,这会使“p”成为“char **”吗?
  2. 这会将“p”指向第一个数组,如预期的那样。
  3. 我猜他们不一样。