C语言指针详解(1)------指针类型(简单例子+详细讲解)

C语言指针类型详解及举例

此文介绍了C语言中常见的6种指针,对每种指针进行了介绍,并举出相应的例子供大家理解学习.

文章目录

C语言指针类型详解及举例1.字符指针2.数组指针3.指针数组4.函数指针5函数指针数组6指向函数指针数组的指针

1.字符指针

字符指针是指向字符数组或字符串的指针。在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.";

2.数组指针

数组指针是指向数组的指针。在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.

3.指针数组

指针数组是指一个数组,其中的元素都是指针类型。换句话说,指针数组是由指针组成的数组。

在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;

4.函数指针

函数指针是指向函数的指针变量,它可以用来存储和调用函数的地址。在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;

}

运行结果如下:

5函数指针数组

函数指针数组是一个数组,其中的元素都是函数指针。换句话说,函数指针数组是由函数指针组成的数组。

在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;

}

我们可以看到此时代码得到了简化,不需要再去一个个调用每个功能,只需要用到转移表,这就是函数指针数组的强大功能.

6指向函数指针数组的指针

它在我们写代码时很少用到,作为一个扩展,我用一个简单的例子让大家了解一下

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;//指向函数指针数组的指针

Java为什么要使用内部类?
10款电视K歌软件深度测评,第一个最好用,伴奏多,MV多,随你嗨唱