在C语言中有一种指针类型为字符指针 char*,常用其来表示字符,使用如下:
#include
int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}
除了上述用法之外,还可以有以下的用法:
int main()
{
const char* pstr = "hello word";
printf("%s\n", pstr);
return 0;
}
在上面的代码中,字符 " hello word "是常量字符串,将"hello word"放入 pstr 指针的实质是将第一个字符 “ h " 的地址传递给了 pstr ,通过首字符 ” h " 就可以访问整个字符串。
注意:常量字符串传递给不同的字符指针变量的时候,传过去的地址是相同的,因为常量字符串是存放在静态区的,它的地址是唯一的。
如下面这道例题:
#include
int main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
const char *str3 = "hello bit.";
const char *str4 = "hello bit.";
if(str1 ==str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if(str3 ==str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
数组指针其本质是指针,数组是用来修饰指针的,表明这个指针是用来存放数组的,即其存放的数据类型是数组。
那如何表示呢?
首先,是一个指针,那么一定有
*arr
其次数据类型是数组(以10个整形类型为例),则一定有int [ 10 ]
合起来便是int (*arr)[ 10 ]
,即 arr 是⼀个指针,指向⼀个数组,叫数组指针。
因为[]
与arr结合的优先级要优先于*
,因而要加括号;否则就变为了指针数组(详细见下指针数组)
数组指针类型解析:
int (*p) [10] = &arr;
| | |
| | |
| | p指向数组的元素个数
| p是数组指针变量名
p指向的数组的元素类型
数组指针变量是⽤来存放数组地址的,那怎么获得数组的地址呢?就是我们之前学习的 &数组名
int a[10] = {0};
&a;//得到的就是数组的地址
如果要存放个数组的地址,就得存放在数组指针变量中,如下:
int(*arr)[10] = &a;
使用如下:
//以打印第一个数据为例
printf("%d", *(arr+0));
//等价于:printf("%d", a[0]);
在此处便可以很好看出数组名其实就是数组的首地址,有以下等价式:
*(p + i) = p[i] = arr[i] =*(arr + i) = i[arr]
详情见**“数组名的理解”**:C语言–指针详解(中)–指针的基本使用、指针在数组中的应用
指针数组其本质是数组,指针是用来修饰数组的,表明这个数组是用来存放指针的,即其存放的数据类型是指针。
那如何表示呢?(与上述数组指针对比)
首先,是一个数组(以10个整形类型为例),那么一定有
arr[10]
其次数据类型是指针,则一定有int *
合起来便是int * arr[ 10 ]
,即 arr 是⼀个数组,指向一个由指针组成的数组,叫指针数组。
因为[]
与arr结合的优先级要优先于*
,因而不用加括号。
指针数组类型解析:
int* p [10] = &arr;
| | |
| | |
| | p指向数组的元素个数
| p是指针数组变量名
p指向的数组的元素类型
char p1 = 'a';
char p2 = 'b';
char p3 = 'c';
char p4 = 'd';
int* arr[10] ={ &p1, &p2, &p3, &p4 };
指针数组一般用于存放多个指针类型的数据,且一般不单独使用,主要用于组成转移表,详细见下转移表。
函数指针变量是⽤来存放函数地址的,通过地址就能够调⽤函数。
其基本形式为:int (*arr) (int,int)
函数指针类型解析:
int (*pf3) (int x, int y)
| | ------------
| | |
| | pf3指向函数的参数类型和个数的交代
| 函数指针变量名
pf3指向函数的返回类型
int (*) (int x, int y) //pf3函数指针变量的类型
有以下三种形式:
void test()
{
printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)()= test;//函数名在本质上也是地址,&函数名==函数名
int Add(int x, int y)
{
return x+y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add;//x和y写上或者省略都是可以的
通过函数指针调⽤指针指向的函数。
#include
int Add(int x, int y)
{
return x+y;
}
int main()
{
int(*pf3)(int, int) = Add;
printf("%d\n", (*pf3)(2, 3));
printf("%d\n", pf3(3, 5));
return 0;
}
输出结果:
5
8
把函数的地址存到⼀个数组中,那这个数组就叫函数指针数组。
基本形式:int (*parr1[3])();
parr1 先和 [ ] 结合,说明parr1是数组,数据类型是 int ( * )( ) 类型的函数指针
函数指针数组的⽤途:转移表
举例:计算器的⼀般实现:
#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(" 0:exit \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");
break;
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 }; //转移表
do
{
printf("*************************\n");
printf(" 1:add 2:sub \n");
printf(" 3:mul 4:div \n");
printf(" 0:exit \n");
printf("*************************\n");
printf( "请选择:" );
scanf("%d", &input);
if ((input <= 4 && input >= 1))
{
printf( "输⼊操作数:" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
printf( "ret = %d\n", ret);
}
else if(input == 0)
{
printf("退出计算器\n");
}
else
{
printf( "输⼊有误\n" );
}
}while (input);
return 0;
}
字符指针、数组指针、指针数组、函数指针、函数指针数组涵盖了在指针学习中有关指针的绝大多数的情况,熟练掌握它们,将对学习指针有巨大的帮助。同时,指针部分是C语言学习中重要的部分之一,熟练掌握指针对于C语言学习来说很重要。