1.定义:指针是以内存地址为值,通过该地址能直接或者间接寻到所需的内存单元。
2.c语言之所以强大,以及它令人着迷的自由性和灵活性,主要来源于指针。
3.指针的用途:
(1)指针允许程序员以更简洁的方式引用大规模的数据结构。数组就是一种较大的数据结构,它由多个数据构成,对数组元素的引用就是由指针来实现的,而数组名本身就是一个指针。
(2)指针允许程序的不同部分能够共享数据。——函数之间的传址传值。
(3)利用指针,能够在程序执行过程中预留新的内存空间。——动态获得内存空间。
(4)指针可以用来记录数据项之间的关系。
(5)指针可以引用函数,将函数作为参数进行传递。
(1)形式: 类型 * 指针变量名;
(2)指针变量的大小取决于电脑是32位还是64位:
32位的是4个字节;64位的是8个字节。
(3)指针变量的写法举例:int *p;
注意:指针初始化很重要,否则变量会变成野指针变得很危险,而且此时指针指向的任意的地址而编译器不会报错。
(1)int *p=NULL;
(2) int i;int *p=&i;
int i; int *p=&i;
i=0; 和 *p=0;等价
指针变量存的是地址,而本身在内存上占一个空间,也是一个地址。
(1)指针变量可以进行算术运算的:自增、自减、加减一个整数,但是不能乘法和除法运算。运算的结构就是指针指向前或后的地址。
(2)指针和指针之间可以做减法运算,得到的是两个地址之间有几个该和指针类型相同的元素。——注:其它指针与指针之前都运算都是违法的。
定义一维数组:int x[6]={1,2,3,4,5,6};
此时一维数组的空间如下:
(1)在数组中,作为数组的首元素的数组名x是一个地址常量,也叫指针常量。此时的数组名x是不能被修改的。
(2)数组的最大特点之一,所占的内存空间是连续的。
运算符 [ ]其实就是指针的另一种形式,
例如:a[2]=*(a+2)=2[a]。所以给指针访问数组带来了方便。
//访问数组的形式有一下三种
int a[6], i;
for (i = 0; i < 6; i++)
{
scanf("%d", &a[i]);
printf("%d ", a[i]);
}
int a[6], i;
for (i = 0; i < 6; i++)
{
scanf("%d", a+i);
printf("%d ", *(a+i));
}
int a[6];
int *p = a;
for (; p < &a[6}; p++)
{
scanf("%d", p);
printf("%d ", *p);
}
(3)操作符之间的优先级问题!
*和++优先级相同,结合方向自右向左,所以指针和自增自减的时候,尽量加上();
#include
int main()
{
int a[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
int sum = 0;
int i, j;
int(*q)[4] = a;//行指针的声明,指向二维数组a的首行
for (i = 0; i < 3; i++)
{
sum = 0;
printf("第%d行(", i + 1);
for (j = 0; j < 4; j++)
{
printf("\t%d", *(*q + j));//由于q指向了二维数组a的首行数据,因此*q相当于a[0],即*a,那么*q+j就是a[0][j]的地址,所以*(*q + j)就是a[0][j]
sum += *(*q + j);
}
printf(")的行和是:%d。\n", sum);
}
return 0;
}
①指针数组在字符串中的运用:用指针数组来接受多个字符串和用二维数组来接受字符相比,指针数组所用的空间会小一点。
②指针数组声明形式:类型 * 指针数组名[数组长度];
一级指针为int *p=NULL;
指向一级指针的指针变量称为二级指针,也是用来存放地址;
声明形式:int **p1=&p;
函数传参有两种:①传值传参②传址传参
第一种方式相当于将实参的值拷贝给了形参
第二种方式是将地址传给形参,形参通过地址可以找主函数中的变量,从而实现了数据共享。
返回来的地址可以访问一个或者一段数据,从而实现了函数返回多个值的功能能——一般情况下,函数只能返回一个值!
(1)
①数据指针:指向整数、实数、字符、数组的指针。
函数指针:指向函数的指针。
②函数指针的相关介绍:在c语言中,函数名代表函数的入口地址。当程序在执行过程中调用某函数时,程序控制转移位置就是该函数名表示的该函数代码的入口地址。当一个指针存放该入口地址,就称该指针为指向函数的指针,简称函数指针。
③函数指针变量的声明形式:
例如程序以定义函数f:
float f(int x,int y);
则可以定义函数指针p:
float (*p)(int ,int );
并给函数指针p赋值:
p=f;
④函数指针的举例:
//指针和函数
//函数指针的主要用途是将一个函数作为另一个函数的参数
//求某个函数的定积分
#include
//定义integral来实现求积分的值(根据同用的积分公式来定义)
double integral(double(*func)(double), int a, int b)
{
return (b - a)*((*func)(a)+(*func)(b)) / 2;
}
//函数1
double f1(double x)
{
return sin(x)*cos(x);
}
//函数2
double f2(double x)
{
return x*x / 2;
}
int main()
{
//定义一个函数指针
double(*p)(double);
p = f1;//求得是f1
printf("%lf\n", integral(p, 1, 2));//输出函数integral返回来的f1积分值
p = f2;//求得是f2
printf("%lf\n", integral(p, 1, 2));//输出函数integral返回来的f2积分值
return 0;
}
⑤指针函数调用函数的格式:
(*函数指针名)(实参表);
(2)函数指针和数据指针的区别
①数据指针指向内存中的数据存储区;而函数指针则是指向程序代码存储区。
②目标运算符作用于数据指针,是用来访问指针所指向的数据;而目标运算符作用于函数指针,则是将程序控制转移到指针所指向的函数入口,执行函数体。
③数据指针可以进行自增和自减等运算;函数指针则不能进行这些运算