一、认识指针
1.什么是指针?
指针是C语言中的一种特殊数据类型,它存储了一个内存地址的值。换句话说,指针==地址。
2.什么是指针变量?
指针变量==存放地址的变量
2.1 如何定义一个指针变量?*
#include<stdio.h>
int main()
{
//什么是整形变量-----存放整形数的变量
//什么是字符变量-----存放字符型数据的变量
//什么是指针变量-----存放指针的变量
//什么是指针变量-----存放地址的变量
int a = 10;
int *p; //这里的*符是一个标识符,告诉系统是一个指针变量,用来保存别人的地址,与下方的*不同
p = &a;
printf("变量名访问a = %d\n",a);
printf("a的地址是0x%p\n",&a);
printf("地址访问a:%d\n",*(&a));
printf("指针变量的方式访问a:%d\n",*p);
return 0;
}
*符的标识作用:只产生在指针变量定义或声明的时候
如何使用一个指针变量?*符的运算作用
2.2变量访问的两种方式
1)直接访问:变量名进行的访问
2)间接访问:将变量i的地址存放在另一个变量中,然后通过该变量来找到变量i的地址,从而访问i变量
3.既然指针变量是存放别人地址的变量,那么为什么要区分类型呢?
第一、决定指向空间的大小
int *pint;----4个字节
char *pchar;-----1个字节
第二、决定地址增量
4.为什么要用指针?
1)动态内存分配:通过指针,我们可以动态地分配内存,创建所需的变量和数据结构。
2)函数参数传递:通过将指针作为函数参数,我们可以在函数内部修改传递给函数的变量的值。
3)数组和字符串操作:指针使我们能够有效地遍历、修改和处理数组和字符串中的元素。
4)数据结构遍历:指针允许我们遍历和操作复杂的数据结构,如链表、树等。
eg:练习1:
//输入三个数a,b,c; 要求不管怎么输入,在输出的时候,a,b,c就是由大到小的顺序输出,用函数封装实现
#include<stdio.h>
void sortData(int *xdata,int *ydata,int *zdata)
{
int temp;
if(*xdata < *ydata){
temp = *ydata;
*ydata = *xdata;
*xdata = temp;
}
if(*xdata < *zdata){
temp = *zdata;
*zdata = *xdata;
*xdata = temp;
}
if(*ydata < *zdata){
temp = *zdata;
*zdata = *ydata;
*ydata = temp;
}
}
int main()
{
int x;
int y;
int z;
printf("请输入三个整数:");
scanf("%d%d%d",&x,&y,&z);
sortData(&x,&y,&z);
printf("这三个数从大到小输出为:%d,%d,%d\n",x,y,z);
return 0;
}
二、通过指针引用数组
1.指针增量和数组的关系
2.通过指针引用数组元素
①下标法
#include<stdio.h>
int main()
{
int i;
int arr[3] = {1,2,3};
int *p;
//p = &arr[0];---数组的首地址就是首个元素的地址
p = arr; //数组名就是数组的首地址
for(i=0;i<3;i++){
printf("%d ",*p);
p++;
}
p = arr;
for(i=0;i<3;i++){
printf("%d ",*p++);
}
}
②指针法
#include<stdio.h>
int main()
{
int i;
int arr[3] = {1,2,3};
int *p;
p = arr; //数组名就是数组的首地址
for(i=0;i<3;i++){
printf("%d ",*(p+i));
}
}
注:数组名和指针的区别
数组名---作为常量指针,是指向常量数据的指针,它的值不能被修改。常量指针可以通过改变它所指向的地址来指向另外的常量数据,但是不能通过指针来修改所指向的值。
指针作为指针变量(存放地址变量),可以指针来修改所指向的值。
三、指针和二维数组
二维数组==‘父子数组’
而二维数组本质上还是一维数组,不同的是数组元素还是个数组(子数组)
3.1.eg:int a[3][4];定义这么一个二维数组;a[0],a[1],a[2]既是一维数组名。
而C语言规定数组名代表数组首元素的地址,因此a[0]代表一维数组中第0列元素的地址,即a[0][0],依次类推。
思考问题:a是谁的地址?a[0]又是谁的地址?*a或者*(a+0)代表了什么?
a是父数组的地址,a[0]是子数组的地址
*a代表取出的则是第0列元素的值,*a = *(a+0) = *a[0]
3.2.地址关系图如下:
3.3.总结:(面试有可能同到)
四、数组指针
数组指针才是真正等同于二维数组名
五、函数指针
5.1 定义:如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址(又称入口地址)称为这个函数的指针。函数名就是地址
六、指针数组
6.1什么是指针数组?
一个数组,若元素均为指针类型数据,称为指针数组。也就是说,指针数组中的每一个元素都存放一个地址,相当于指针变量。
#include<stdio.h>
int getTheMax(int data1,int data2)
{
return data1 > data2 ? data1 : data2;
}
int getTheMin(int data1,int data2)
{
return data1 < data2 ? data1 : data2;
}
int getTheSum(int data1,int data2)
{
return data1 + data2;
}
int dataHeadler(int data1,int data2,int (*pfunc)(int data1,int data2))
{
int ret;
//ret = (*pfunc)(data1,data2);
ret = pfunc(data1,data2);
return ret;
}
int main()
{
int a;
int b;
int ret = 0;
int cmd;
int (*pfunc)(int data1,int data2);
printf("请输入两个数:\n");
scanf("%d%d",&a,&b);
getchar();
printf("请输入执行哪一步操作,1--输出最大数,2--输出最小数,3--输出他们的和\n");
scanf("%d",&cmd);
switch(cmd){
case 1:pfunc = getTheMax;
break;
case 2:pfunc = getTheMin;
break;
case 3:pfunc = getTheSum;
break;
default:printf("输入错误!@1--输出最大数,2--输出最小数,3--输出他们的和\n");
break;
}
ret = dataHeadler(a,b,pfunc);
printf("ret = %d\n",ret);
return 0;
}