数组指针与C中的常规指针

时间:2014-04-17 18:45:43

标签: c arrays pointers

我是C的初学者,请与我的无知一起工作。为什么是普通指针

int* ptr = &a;在内存中有两个空格(一个用于指针变量,一个用于指向的值),数组指针int a[] = {5};只有一个内存空间(如果我打印出来

printf("\n%p\n", a)我得到的地址与打印出来的地址相同:printf("\n%p\n", &a)

问题是,是否应该有一个指针变量a的内存空间,以及一个指向第一个数组元素的值的内存空间?它使用常规指针int* ptr = &a;

来完成

6 个答案:

答案 0 :(得分:2)

你的问题有点不清楚(假设没有编译器优化),但如果你先声明一个变量然后指向该变量的指针,

int a = 4;
int *p = &a;

那么你有两个不同的变量,有两个内存插槽是有意义的。您可以将p更改为指向其他内容,并且仍然希望引用稍后的

int a = 4;
int b = 5;

int *p = &a; // p points to a

// ...

p = &b; // now p points to b
a = 6; // but you can still use a

数组声明只是在堆栈上分配内存。如果你想在堆上用指针做同样的事情,你会使用像malloc或calloc(或c ++中的new)这样的东西

int *p = (int*)malloc(1 * sizeof(int));
*p = 4;

但当然记得稍后将其释放(在c ++中删除)

free(p);
p = 0;

答案 1 :(得分:1)

这里的主要误解是&a没有返回指针指向预期的指针,因为在C语言中,[]和*之间存在一些差异(这里的解释:Difference between [] and *) 如果你尝试&a如果a是一个指针(例如int * a)那么你获得一个新的内存位置但是当你使用一个静态数组(即int a [])然后它返回第一个数组元素的地址。我还将尝试通过下一个代码块来澄清这个问题。

#include <stdio.h>

int main(int argc, char *argv[])
{
    // for cycles
    int k; 

    printf("That is a pointer case:\n");
    // Allocate memory for 4 bytes (one int is four bytes on x86 platform, 
    // can be differ for microcontroller e.g.)
    int c = 0xDEADBEEF;
    unsigned char *b = (unsigned char*) &c;
    printf("Value c: %p\n", c);
    printf("Pointer to c: %p\n", &c);
    printf("Pointer b (eq. to c): %p\n", b);
    // Reverse order (little-endian in case of x86)
    for (k = 0; k < 4; k++)
        printf("b[%d] = 0x%02X\n", k, b[k]);

    // MAIN DIFFERENCE HERE: (see below)    
    unsigned char **p_b = &b;
    // And now if we use & one more we obtain pointer to the pointer
    // 0xDEADBEEF <-- b <-- &p_b
    // This pointer different then b itself
    printf("Pointer to the pointer b: %p\n", p_b);

    printf("\nOther case, now we use array that defined by []:\n");
    int a[] = {5,1};
    int *ptr = &a;
    // 'a' is array but physically it also pointer to location
    // logically it's treat differ other then real pointer
    printf("'a' is array: %x\n", a);
    // MAIN DIFFERENCE HERE: we obtain not a pointer to pointer
    printf("Pointer to 'a' result also 'a'%x\n", &a);
    printf("Same as 'a': %x\n", ptr);
    printf("Access to memory that 'a' pointes to: \n%x\n", *a);

    return 0;
}

答案 2 :(得分:0)

这很简单。在第一种情况下,

int* ptr = &a;

您已经声明了一个变量a,因此存在于内存中。现在你声明另一个变量ptr(用于保存地址,在C变量中保存另一个变量的地址称为指针),这再次需要内存的方式与{{1}相同} required。

在第二种情况下,

a

您只需声明一个变量(将包含int a[] = {5};的集合),因此会为ints相应地分配内存。

答案 3 :(得分:0)

在这个表达式中,int* p = &a; p只有一个内存位置,最可能是CPU的WORD大小,用于存储另一个的地址(内存位置)变量

执行*p时,您解除引用 p,这意味着您将获得 p指向的值。在这种特殊情况下,这将是a的值。 a 在内存中有自己的位置p只有指向它,但本身并不存储a的内容。

如果你有一个数组,比如int a[] = {5};,那么你有一系列(或一个)内存位置,并且它们充满了值。这些是实际的位置。

C中的数组可以衰减指针,所以当你printf就像使用数组一样,无论你做a还是{&a,都会得到相同的地址{1}}。这是因为数组到指针衰减

a仍然是同一个位置,而且只是该位置。 &a实际上返回一个指向a的指针,但该指针位于内存中的其他位置。如果您int* b = &a; b,那么aa的位置不同,但指向 {{1}}。

答案 4 :(得分:0)

ptr是一个包含内存地址的变量。您可以为ptr分配各种内存地址。 a是表示数组第一个元素的固定内存地址的常量。你可以这样做:

ptr = a;

但不是

a = ptr;

答案 5 :(得分:-1)

指针指向内存中的某个区域。指向int的指针指向一个足以容纳int类型值的区域。

如果你有一个int数组并使指针指向数组第一个元素

int array[42];
int *p = array;

指针仍然指向足够宽的空间以用于int。

另一方面,如果你指向一个不同的指针指向整个数组,这个新指针指向一个从同一地址开始的更大区域

 int (*q)[42]; // q is a pointer to an array of 42 ints
 q = &array;

pq的地址相同,但它们指向不同大小的区域。