C 按值传递函数参数。因此,要允许函数修改调用者提供的变量,必须传递指向它的指针。并且函数必须取消引用指针才能进行修改。
void foo_1 (int a) {
a += 1; /* caller will not see any change to a */
}
void foo_2 (int *ap) {
*ap += 1; /* caller will see value has changed */
}
int a = 0;
foo_1(a); /* a is still 0 after return */
foo_2(&a); /* a becomes 1 after return */
运算符产生一个值,该&
值表示它所应用到的对象的地址,结果类型是“指向(对象类型)的指针”。在上面的例子中,结果&a
是“pointer to int
”。
如果变量是指针类型,则根本没有什么不同。
void foo_1 (int *a) {
a = malloc(sizeof(int)); /* caller will not see any change to a */
}
void foo_2 (int **ap) {
*ap = malloc(sizeof(int)); /* caller will see value has changed */
}
int *a = 0;
foo_1(a); /* a is still 0 after return */
foo_2(&a); /* a becomes initialized to memory allocated by malloc */
在上面的例子中,因为a
是指向的指针int
,所以类型&a
是“指向指针的指针int
”。
指针是用来指代对象地址的术语。对象的地址是一个值,表示对象在内存中的位置。知道该地址意味着可以读取和修改对象。指针变量是可以存储对象地址的变量。
通常,变量的名称用于表示对象。所谓对象,我只是指变量使用的内存,以及它的语义表示,也就是它的类型(通常,术语变量和对象可以互换使用,但对我来说,区别在于变量有一个名称)。读取和修改对象是通过名称完成的。获得指向对象的指针的一种方法是将一元运算&
符应用于变量的名称。因此,保存该地址的指针变量是指向该对象的指针。现在,可以通过使用一元运算符取消引用指针,通过指针读取和修改同一个对象*
。
int a = 0;
int *ap = &a;
a += 1; /* a now has the value 1 */
*ap += 1; /* a now has the value 2 */
动态创建的对象,即 through malloc()
,没有名称。但是,malloc()
返回一个指针,通过该指针可以读取和修改对象。
int *ap = 0; /* ap initialized to NULL */
ap = malloc(sizeof(int)); /* ap points to dynamically allocated int */
*ap = 0; /* int pointed to by ap now holds value 0 */
*ap += 1; /* int pointed to by ap now holds value 1 */
您的allocateArray()
函数将指针的这两种用法结合到一个函数中。
int *vector = NULL; /* vector is pointer to int variable initialized to NULL */
allocateArray(&vector,5,45); /* the address of vector is passed to allocateArray */
由于 vector 的地址被传递给allocateArray()
,因此该函数现在可以vector
通过引用它收到的指针值来修改命名的对象。在参数中接收到指针值arr
:
void allocateArray( int **arr, size_t size, int value )
并且,通过取消引用arr
,它vector
使用返回的值更新对象malloc()
:
*arr = malloc( size * sizeof( int ));
如果分配,内存的初始化,然后vector
变量的更新分多个步骤进行,函数可能会更清晰。
void allocateArray( int **arr, size_t size, int value )
{
int *vec = malloc( size * sizeof( int )); /* vec points to size contiguous int */
if ( vec != NULL )
for ( size_t i = 0; i < size; ++i )
vec[i] = value; /* vec[i] set to value */
*arr = vec; /* return vec into first parameter */
}