指针就是内存地址,使用指针访问变量,就是直接对内存中的数据进行的操作。
合理地使用指针,可以提高程序运行的速度,增强操作的灵活性。
访问内存中的数据有两种方式:直接访问和间接访问。直接访问就是通过变量来实现,因为变量是内存中某一块存储区域的名称;间接访问就是通过指针来实现。指针并不是用来存储数据的,而是用来存储数据在内存中的地址,我们可以通过访问指针达到访问内存中数据的目的。
11.1指针概述
指针是内存数据的快捷方式。
11.1.1内存地址
计算机程序中使用的所有数据,都必须存储在计算机的存储单元中,并且应能从计算机的存储单元中取出。每个存储单元都有唯一的地址。
计算机内存被划分成按顺序编号的内存单元,这就是地址。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。
变量是内存中某一块存储区域的名称,对变量赋值就相当于把值存储到该存储区域中,比如下图
11.1.2内存和指针
变量的内存地址就是变量的指针。如果有一个变量专门用来存放另一个变量的指针,则称为指针变量。下图所示的p就是一个指针变量。变量p中存放的是变量i 的指针(地址),变量p就是指向 i 的指针变量。
3)指针变量中只能存放指针(地址),不要将一个非零数(或任何其他非地址类型的数据)赋给一个指针变量。
11.2指针变量
11.2.1初始指针变量
指针变量也是变量。
假如该指针变量名叫做p,变量p的用途比较特殊,它代表的存储单元中存储的是另外一个变量的地址,假如该变量名叫a,可以理解为这个指针变量P指向变量a。当然可以直接访问a,从而获得a的数据,也可以间接地通过访问p来获得a的数据。
* 称为指针运算符,它表示获取指针变量所指向的变量的值,这是非常重要的。
对于指针变量p,如果在程序中使用了指针运算符,也就是使用了*p,那么*p表示指针p指向的存储单元的值,也就是变量 i 的值,从数值意义上理解,二者是一样的。
11.2.2使用指针变量
多运用使用,达到熟练掌握
#include <stdio.h>
#pragma warning(disable:4996)
int main() {
int a, b, c;
int *p1 = &a, *p2 = &b, *p3 = &c, *p;
printf("请输入变量a,b,c\n");
scanf("%d %d %d", &a, &b, &c);
if (*p1 < *p2) {/*当*p1小于*p2时交换*/
p = p1;
p1 = p2;
p2 = p;/*p1最大*/
}
if (*p1 < *p3) {/*当*p<*p3时*/
p = p1;
p1 = p3;
p3 = p;/*p1最大*/
}
//此时已确定*P1为最大值,只要比较后面两个即可
if (*p2 < *p3) {
p = p2;
p2 = p3;
p3 = p;/*p2为第二大*/
}
/*按顺序输出*/
printf("按从小到大排序\n");
printf("%d %d %d\n", *p1, *p2, *p3);
system("pause");
return 0;
}
11.2.3指针的运算
指针的运算就是地址的运算,由于这一特点,指针运算不同于普通变量,只允许有限的几种运算。除了可以对指针赋值外,指针的运算还包括移动指针、两个指针相减、指针与指针或指针与地址之间进行比较等。可以通过将指针加减一个整数,或者通过对指针赋值来移动指针。
例如:p+n、p-n、p++、++p、和--p等,其中n是整数。
将指针p加上或者减去一个整数N,表示p向地址增加或减小的方向移动N个元素单元,从而得到一个新的地址,使其能访问新地址中的数据。每个数据单元的字节数取决于指针的数据类型。
11.3指针与函数
11.3.1指向函数的指针
用指针变量可以指向一个函数。函数在程序编译时被分配了一个入口地址,这个函数的入口地址就称为函数的指针。
函数指针变量常用的用途之一是把指针作为参数传递到其他函数。指向函数的指针也可以作为参数,以实现函数地址的传递,这样就能够在被调用的函数中使用实参函数。
int (*p)(int,int)说明p是一个指向函数的整型指针。c=(*p)(a,b)说明p确切指向函数max,相当于调用了c=max(a,b);
int (*p)(int,int)是一个函数指针
11.3.2返回指针的函数
函数可以返回数值型、字符型、布尔型等数据,也可以带回指针型的数据叫做返回指针值的函数。
类型名 *函数名(参数表列);
例如下式表示的含义是:max函数调用后返回值的数据类型是整型指针。
int *max(int *x,int *y);
#include <stdio.h>
int *max(int x[], int y[], int *p, int *c);
int main() {
int c1[10] = { 1,2,3,4,5,6,7,8,9,0 };
int c2[10] = { 11,12,13,14,15,16,17,18,19,10 };
int n;
int c;
int *p;
p = max(c1, c2, &n, &c);//将值赋值给n,c
printf("两个数组中最大的是%d,在%d中位置是%d\n", *p, c, n);/*函数max返回最大值*/
system("pause");
return 0;
}
/*返回指针的函数*/
int *max(int x[], int y[], int *p, int *c) {
int i;
int *m = &x[0];
for (i = 0; i < 9; i++)
{
if (*m < x[i]) {
*m = x[i];
*p = i;//*p=8,并传递给&n;
*c = 1;
}
}
for (i = 0; i < 9; i++)
{
if (*m < y[i]) {
*m = y[i];
*p = i;
*c = 2;//将值赋值给&c;
}
}
return m;
}
11.4 void指针类型
void指针类型,可以用来指向一个抽象类型的数据,在将它的值赋给另一个指针变量时要进行强制类型转换,使之适合于被赋值的变量的类型。
可以通过一个具体的例子来说明void指针类型的含义和用法,代码如下:
char *p1;
void *p2;
p1 = (char *)p2;
同样可以使用(void *)p1将p1转换成 void* 类型,代码如下:
p2=(void *)p1;
不只对变量可以使用 void 指针类型,也可以将一个函数定义为 void *类型。比如下面的代码,表示函数fun 返回的是一个地址,它指向空类型,如需要引用此地址,也需要根据情况对之进行类型转换,如对该函数调用得到的地址要进行以下转换。
void * fun(char ch1,char ch2);
p1=(char *)fun(ch1,ch2);
欢迎关注微信号:魅影响
或扫描下方二维码关注