学习C – C指针
指针指向另一个值的内存地址。
指针引用内存中的位置,并获取存储在该位置的值称为取消引用指针(来源:http://en.wikipedia.org/wiki/Pointer_(computer_programming))。
看下面的语句:
int number = 5;
分配一个内存位置来存储值为5的整数,您可以使用名称编号访问它。
值5存储在该区域中。
计算机使用地址引用该区域。
假设地址是101。我们可以说把价值5放入房间号101;
可以存储地址的变量称为指针。
下面的代码定义了一个指针 number
其中包含另一个变量的地址,称为number,它是一个包含值5的整数变量。
存储在数字中的值是地址的第一个字节数。
字指针用于仅指一个地址。
int number = 5; int *pnumber = &number;
指向char类型的值的指针指向占用1个字节的值,而指针到类型long的值通常指向占用4个字节的值的第一个字节。
每个指针将与特定的变量类型相关联,并且它只能用于指向该类型的变量。
因此,类型“指向int的指针”的指针只能指向int类型的变量,“指向浮点型”指针的指针只能指向float类型的变量,等等。
通常,给定类型的指针对于任何给定的类型名称类型写为*。
类型名称void表示不存在任何类型,因此类型为void *的指针可以包含数据的地址任何类型的项目。
类型void *通常用作具有处理数据的函数的参数类型或返回值类型以类型无关的方式。
任何类型的指针可以作为类型void *的值传递,然后转换为适当类型使用时。
类型为int的变量的地址可以存储在指针变量中例如,类型为void *。
当你想访问存储在void *指针中的地址的整数值时,你必须首先将指针转换为int *类型。
声明指针
您可以使用以下语句声明指向int类型的变量的指针:
int *pnumber;
具有名称number的变量的类型为int *。
它可以存储int类型的任何变量的地址。
注意,你也可以写这样的语句:
int* pnumber;
语句只是创建pnumber变量,但不会初始化它。
你可以初始化pnumber,使它不会通过重写声明来指向任何东西喜欢这个:
int *pnumber = NULL;
NULL是在标准库中定义的常量,并且对于指针等效于零。
NULL是一个值,不能指向内存中的任何位置。
如果要使用变量的地址初始化变量pnumber你已经声明,你使用运算符的地址&:
int number = 5; int *pnumber = &number;
现在,number的初始值是变量的地址。
您可以在中声明常规变量和指针同样的语句,例如:
double value, *pVal, fnum;
此语句声明两个双精度浮点变量,值和fnum,以及变量pVal类型“指针加倍。
例子
为了获得变量的内存地址,我们可以使用& 句法。
#include <stdio.h>
int main(int argc, const char* argv[]) {
int n;
n = 10;
printf("value n: %d \n",n);
printf("address n: %x \n",&n);
return 0;
}
上面的代码生成以下结果。
注意
要声明一个特定数据类型的指针,我们可以使用 *
语法。
此变量由我们的指针变量的内存地址。
#include <stdio.h>
int main(int argc, const char* argv[]) {
int n;
int* nPtr;
n = 10;
nPtr = &n;
printf("value n: %d \n",n);
printf("address n: %x \n",(unsigned int)&n);
printf("value nPtr: %x \n",(unsigned int)nPtr);
printf("address nPtr: %x \n",(unsigned int)&nPtr);
printf("value pointer nPtr: %d \n",*nPtr);
return 0;
}
你可以看到nPtr的值是变量n的内存地址。
如果n设置为10,那么指针nPtr的值,我们声明为* nPtr是与变量n的值相同的值。
上面的代码生成以下结果。
通过指针访问值
使用间接运算符*来访问指针指向的变量的值。
这个操作符也是称为解引用运算符,因为您使用它来“解引用”指针。
假设您声明以下变量:
int number = 15; int *pointer = &number; int result = 0;
指针变量包含变量号的地址,因此可以在表达式中使用此变量计算结果的新值,如下所示:
result = *pointer + 5;
表达式*指针将计算存储在指针中包含的地址处的值。
这是值存储在数字,15,因此结果将设置为15 + 5,这是20。
下面的代码声明一个变量和一个指针,然后输出它们的地址和值。
#include <stdio.h>
int main(void)
{
int number = 0; // A variable of type int initialized to 0
int *pnumber = NULL; // A pointer that can point to type int
number = 5;
printf("number"s address: %p\n", &number); // Output the address
printf("number"s value: %d\n\n", number); // Output the value
pnumber = &number; // Store the address of number in pnumber
printf("pnumber"s address: %p\n", (void*)&pnumber); // Output the address
printf("pnumber"s size: %zd bytes\n", sizeof(pnumber)); // Output the size
printf("pnumber"s value: %p\n", pnumber); // Output the value (an address)
printf("value pointed to: %d\n", *pnumber); // Value at the address
return 0;
}
上面的代码生成以下结果。
指针用法
因为您可以通过指针pnumber访问数字的内容,您可以在算术语句中使用取消引用的数值类型的指针。
例如:
*pnumber += 5;
此语句将当前所有地址变量pnumber的值递增5。
*表示正在访问名为pnumber的变量所指向的内容。
变量pnumber可以存储int类型的任何变量的地址。
这意味着您可以将pnumber指向的变量更改为:
int value = 9; pnumber = &value;
假设您重复以前使用的相同语句:
*pnumber += 5;
语句将使用新的变量,值操作,因此值的新内容将为14。
指针可以包含适当类型的任何变量的地址,因此可以使用一个指针变量来更改值许多不同的变量,只要它们的“re”类型与指针类型兼容即可。
此示例使用指针修改存储在一些其他变量中的值。
#include <stdio.h>
int main(void)
{
long num1 = 1L;
long num2 = 1L;
long *pnum = NULL;
pnum = &num1; // Get address of num1
*pnum = 2L; // Set num1 to 2
++num2; // Increment num2
num2 += *pnum; // Add num1 to num2
printf("num1 = %ld num2 = %ld *pnum = %ld *pnum + num2 = %ld\n",
num1, num2, *pnum, *pnum + num2);
return 0;
}
上面的代码生成以下结果。
例2
以下代码显示了如何在 scanf
函数中使用指针变量。
当您使用scanf()输入值时,您已经使用&运算符来获取要接收输入的变量的地址。
当你有一个指针时,可以使用指针名称作为参数。
#include <stdio.h>
int main(void)
{
int value = 0;
int *pvalue = &value; // Set pointer to refer to value
printf ("Input an integer: ");
scanf(" %d", pvalue); // Read into value via the pointer
printf("You entered %d.\n", value); // Output the value entered
return 0;
}
上面的代码生成以下结果。