此文介绍了C语言中常见的6种指针,对每种指针进行了介绍,并举出相应的例子供大家理解学习.
字符指针是指向字符数组或字符串的指针。在C语言中,字符串实际上是以null字符(‘\0’)结尾的字符数组。字符指针指向这个字符数组的首地址。
例如,有一个字符串 “Hello”,可以用字符数组来表示:char str[] =“Hello”。而字符指针则指向这个字符数组的首地址,可以这样声明:char *ptr = str;。
通过字符指针,我们可以访问和操作字符串中的字符,也可以通过指针算术运算来遍历字符串。常见的字符串操作函数如strlen、strcpy、strcat等也都是通过字符指针进行操作的。
需要注意的是,字符指针指向的字符数组应该是以null字符(‘\0’)结尾的,以便正确识别字符串的结束。否则,可能会导致访问越界或其他错误。
使用举例
//一,最简单的使用
char ch = 'w';
char *pc = &ch;
*pc = 'w';
//二,字符串使用
const char* pstr = "hello bit.";//这里是把一个字符串放到pstr指针变量里了吗?
printf("%s\n", pstr);//pstr中存放的是字符串首字符‘h’的地址
//代码 const char* pstr = "hello bit.";
数组指针是指向数组的指针。在C语言中,数组名本身就是一个指向数组首元素的指针,即数组的地址就是数组名的值。因此,可以使用指针来操作数组的元素。
例如,有一个整型数组 int arr[5] = {1, 2, 3, 4, 5},可以用数组名 arr
来表示该数组,同时arr也是指向数组首元素的指针,即 int *ptr = arr;。通过数组指针,我们可以访问和操作数组的元素,也可以通过指针算术运算来遍历数组。
需要注意的是,数组指针的类型应该与数组的类型一致,即指向何种类型的数组就应该声明指针类型为该类型的指针。同时,数组指针也可以指向多维数组,只需要指针类型与数组维度相对应即可。
总结来说,数组指针是指向数组的指针,可以通过指针来访问和操作数组的元素。
使用举例
int arr[10]={1,2,3};
&arr;//拿到的是数组的地址
int (*p)[10]=&arr;//p是一个数组指针变量
int (*)[10]//是一个数组指针类型
int arr[10] = { 0 };
printf("arr = %p\n", arr);
printf("&arr= %p\n", &arr);
printf("arr+1 = %p\n", arr+1);
printf("&arr+1= %p\n", &arr+1);
根据上面第二段代码我们发现,其实&arr和arr,虽然值是一样的,但是意义应该不一样的。
实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。(细细体会一下)
本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型
数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40.
指针数组是指一个数组,其中的元素都是指针类型。换句话说,指针数组是由指针组成的数组。
在C语言中,可以声明一个指针数组来存储多个指针。每个数组元素都是一个指针,可以指向不同的数据类型或对象。这使得我们能够在数组中存储不同类型的数据或对象的地址。
使用举例
char *arr[5];//存放字符指针的数组
int *arr2[6];//存放整形指针的数组
例如,假设我们有三个整型变量 int a, int b 和 int c,并希望将它们的地址存储在一个数组中,我们可以这样声明一个指针数组:
具体如下:
int *ptrArr[3]; // 声明一个指针数组,包含三个指针元素
//然后,我们可以将这三个整型变量的地址分别存储到指针数组中:
ptrArr[0] = &a;
ptrArr[1] = &b;
ptrArr[2] = &c;
函数指针是指向函数的指针变量,它可以用来存储和调用函数的地址。在C语言中,函数指针允许将函数作为参数传递给其他函数,或者将函数作为返回值返回。
使用举例
int Add(int x, int y)
{
return x + y;
}
//&函数名 - 拿到的就是函数的地址
//函数名 - 也是函数的地址
int main()
{
printf("%p\n", &Add);
printf("%p\n", Add);
int (* pf)(int, int) = &Add;//pf就是一个函数指针变量
int (* pf)(int, int) = Add;
int ret = pf(3, 5);
int ret2 = Add(3, 5);
printf("%d\n", ret);
printf("%d\n", ret2);
return 0;
}
函数指针数组是一个数组,其中的元素都是函数指针。换句话说,函数指针数组是由函数指针组成的数组。
在C语言中,可以声明一个函数指针数组来存储多个函数指针。每个数组元素都是一个函数指针,可以指向不同的函数。
函数指针数组的用途:转移表
使用举例(计算器)
#include
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
do
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "请选择:" );
scanf( "%d", &input);
switch (input)
{
case 1:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = add(x, y);
printf( "ret = %d\n", ret);
break;
case 2:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = sub(x, y);
printf( "ret = %d\n", ret);
break;
case 3:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = mul(x, y);
printf( "ret = %d\n", ret);
break;
case 4:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = div(x, y);
printf( "ret = %d\n", ret);
break;
case 0:
printf("退出程序\n");
breark;
default:
printf( "选择错误\n" );
break;
}
} while (input);
return 0;
}
我们可以看到如果不使用函数指针数组,我们写一个计算器需要的代码非常繁琐,如果还要再增加功能,那么代码也会更加复杂.
下面使用函数指针数组:
#include
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
while (input)
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "请选择:" );
scanf( "%d", &input);
if ((input <= 4 && input >= 1))
{
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf( "输入有误\n" );
printf( "ret = %d\n", ret);
}
return 0;
}
我们可以看到此时代码得到了简化,不需要再去一个个调用每个功能,只需要用到转移表,这就是函数指针数组的强大功能.
它在我们写代码时很少用到,作为一个扩展,我用一个简单的例子让大家了解一下
int a=10;
int b=20;
int c=30;
int *arr[]={&a,&b,&c};//整形指针数组
int *(*p)[3]=&arr;//p是指针,是指向整形指针数组的指针
//函数指针数组 - 数组 - 存放的是函数的地址
int (*pfArr[5])(int,int)={NULL,Add,Sub,Mul,Div};//pfArr是函数指针数组
p=&pfArr;
int (*(*p)[5])(int,int)=&pfArr;//指向函数指针数组的指针