指针提供一种以符号形式使用地址的方法。因为计算机的硬件指令非常依赖地址,指针在某种程度上把程序员想要传达的指令以更接近机器的方式表达。因此,使用指针的程序更有效率。
#include <stdio.h>
int main()
{
int a;
int *p=&a;
printf("请输入一个整数:");
scanf("%d",&a);//这里用&就是为了获取变量a的地址
printf("a = %d\n",a);
printf("请重新输入一个整数:");
scanf("%d",p);//而指针p本身存放的就是变量a的地址
printf("a = %d\n",a);
return 0;
}
尤其是,指针能有效地处理数组。我们很快就会学到,数组表示法其实是在变相地使用指针。
我们举一个变相使用指针的例子:
flizny == &flizny[0]; // 数组名是该数组首元素的地址
flizny 和&flizny[0]都表示数组首元素的内存地址(&是地址运算符)。
两者都是常量,在程序的运行过程中,不会改变。但是,可以把它们赋值给指针变量,然后可以修改指针变量的值。
#include <stdio.h>
int main()
{
char str[12];
printf("请输入一段英文:");
scanf("%s",str);
printf("str的地址是:%p\n", str);
printf("str的地址是:%p\n", &str[0]);
return 0;
}
现在定义一些指针,并且把他们的地址打印出来
#include <stdio.h>
int main()
{
char a[] = "ABC";
int b[5] = {1, 2, 3, 4, 5};
float c[5] = {1.1, 1.2, 1.3, 1.4, 1.5};
double d[5] = {1.1, 1.2, 1.3, 1.4, 1.5};
printf("a[0] -> %p, a[1] -> %p, a[2] -> %p\n",&a[0],&a[1],&a[2]);
printf("b[0] -> %p, b[1] -> %p, b[2] -> %p\n",&b[0],&b[1],&b[2]);
printf("c[0] -> %p, c[1] -> %p, c[2] -> %p\n",&c[0],&c[1],&c[2]);
printf("d[0] -> %p, d[1] -> %p, d[2] -> %p\n",&d[0],&d[1],&d[2]);
return 0;
}
注意指针加上一个数时,它的值发生了什么变化
现在可以更清楚地定义指向int的指针、指向float的指针,以及指向其他数据对象的指针。
指针的值是它所指向对象的地址。地址的表示方式依赖于计算机内部的硬件。许多计算机(包括PC和Macintosh)都是按字节编址,意思是内存中的每个字节都按顺序编号。这里,一个较大对象的地址(如double类型的变量)通常是该对象第一个字节的地址。
在指针前面使用*运算符可以得到该指针所指向对象的值。
指针加1,指针的值递增它所指向类型的大小(以字节为单位)。
下面的等式体现了C语言的灵活性:
dates + 2 == &date[2] // 相同的地址
*(dates + 2) == dates[2] // 相同的值
也可以用指针来定义字符串,用下标法来读取每一个元素。
#include <stdio.h>
#include <string.h>
int main()
{
char *str = "Hello World";
int i,length;
length = strlen(str);
for (i = 0; i < length; i++)
{
printf("%c",str[i]);
}
printf("\n");
return 0;
}