律师网站建设模板网站源码开发
news/
2025/9/22 17:20:15/
文章来源:
律师网站建设模板,网站源码开发,衡东网站定制,wordpress 会员登录字符指针变量
在指针的类型中我们知道有一种指针叫做字符指针
它的使用情况如下#xff1a;
#includestdio.h
int main()
{char pa w;char*p1pa;*p1 a;printf(%c\n, *p1);return 0;
}
在这段代码当中#xff0c;我们将‘w’字符的地址传到了p…字符指针变量
在指针的类型中我们知道有一种指针叫做字符指针
它的使用情况如下
#includestdio.h
int main()
{char pa w;char*p1pa;*p1 a;printf(%c\n, *p1);return 0;
}
在这段代码当中我们将‘w’字符的地址传到了p1里面而p1就是一个字符指针。
除了上面这种使用方法还有一种关于字符指针变量的使用方法如下
#includestdio.h
int main()
{char* p1 abced;printf(%s\n, p1);return 0;
}
有没有感到很好奇对于这段代码的解释大家有什么想法吗
咱们的第一个反应应该是这个是不是把字符串“abced”放到字符指针p1里面啊但真实情况不是这样的这个是将“abced”中的首字母的地址放到了p1的指针变量当中从而在打印的时候可以通过p1找到字符串首字母的地址从而顺藤摸瓜地打印出整个字符串。
下面呢我们来看一段代码这段代码是一道经典的面试题来自《剑指offer》
#includestdio.h
int main()
{char arr3[] hello,bit.;char arr4[] hello,bit.;char* p1 hello,bit.;char* p2 hello,bit.;if (arr3 arr4){printf(arr3 and arr4 are the same\n);}elseprintf(arr3 and arr4 are not same\n);if (p1 p2){printf(p1 and p2 are the same\n);}elseprintf(p1 and p2 are not same\n);return 0;
}
下面是这段代码运行的结果 这个结果大家想到了吗
其中的原理如下
在数组中用相同的常量字符串初始化数组时系统会开辟不同的内存空间。
而在指针当中两个指针指向的是同一个常量字符串也就是指向同一个开辟下的内存空间。这个就是上面答案的原理所在。
数组指针变量
前面我们讲了指针数组指针数组是一个数组存放的是指针地址而数组指针是一个指针存放的是数组的地址看下面两个 //指针数组和数组指针 //1.int*arr[10] // //2.int(*arr)[10] 大家可以看看这两个哪个是指针数组哪个是数组指针。
很明显第一个是指针数组数组名是arr数组中存放有10个元素每个元素是int*类型
然后第二个是一个数组指针根据优先级考虑在这个当中首先arr应该与*结合构成一个指针然后指向的是一个10个元素的数组数组中的每个元素都是int类型
数组指针变量的初始化
数组指针是一个指针存放的应该是数组的地址那我们怎么可以得到数组的地址呢arr通过这个便可以得到数组的地址
#includestdio.h
int main()
{int arr[10] { 0 };int(*pte)[10] arr;return 0;
} 从这个当中我们可以看到arr和pte的地址是相同的二者指向了同一块内存空间这个就是数组指针变量的初始化。
二维数组传参的本质
有了前面的数组指针变量的基础我们就可以好好地了解一下二维数组传参的内容之前我们写过二维数组传参的内容请看下面的代码
#includestdio.h
void print(int arr[3][4], int r, int j)
{for (int i 0; i r; i){for (int h 0; h j; h){printf(%d , arr[i][h]);}printf(\n);}}
int main()
{int arr[3][4] { {1,2,3,4},{2,3,4,5},{3,4,5,6} };print(arr, 3, 4);return 0;
} 我们在之前的代码当中形参是数组形式实参也是数组的形式除了这个写法我们还有其他的写法吗
我们再来看二维数组二维数组其实可以看成是每个元素都是一维数组的数组然后数组名是数组首元素的地址也就是说实参的第一个参数的意思是二维数组第一行的四个元素的地址所以我们可以在形参部分写成这样
#includestdio.h
void print(int (*ptr)[4], int r, int j)
{for (int i 0; i r; i){for (int h 0; h j; h){printf(%d , *(*(ptri)h));}printf(\n);}}
int main()
{int arr[3][4] { {1,2,3,4},{2,3,4,5},{3,4,5,6} };print(arr, 3, 4);return 0;
}
在这里我们在详细讲一个**ptrih首先先看最里面的那个括号ptr是数组首元素的地址ptri代表着二维数组的第几行的地址然后再加*找到第几行的元素也就是arr[i]然后用arr[i]j代表的是第i行第j列的地址然后在使用解引用符就可以找到该地址所代表的元素然后打印出来就是数组。
数组名是数组首元素的地址
数组名是数组的地址
函数名是函数的地址
函数名也是函数的地址
二维数组传参形参可以形成数组形式也可以写成指针形式。
函数指针变量
通过前面对于指针变量的理解我们大概可以知道函数指针变量应该是一个指针变量指向的应该是函数的地址那么问题来了函数有地址吗让我们来看一下
#includestdio.h
int main()
{printf(printf %p\n, printf);return 0;
} 从上面的结果我们可以看到函数是有地址的函数名就是函数的地址那我们也可以通过函数名来获得函数的地址那我们也可以通过函数地址的调用实现对于函数的调用。
如果我们将函数变量的地址存放起来就可以创建函数指针了函数指针其实和数组指针是极其相似的。
void test()
{printf(hehe);
}
void (*ptr1)() test;
void(*ptr2)() test;int Add(int x, int y)
{return x y;
}
int (*ptr3)(int, int) Add;
int (*ptr4)(int x, int y) Add;//加不加 x,y都是可以的 函数指针类型分析 函数指针变量的使用
通过函数指针调用指针所指向的函数
#includestdio.h
int Add(int x,int y)
{return x y;
}
int main()
{int (*ptr)(int, int) Add;printf(%d\n, (*ptr)(3, 4));printf(%d\n, ptr(3, 4));return 0;
}两段有趣的代码
接下来我们来看两段出自《C陷阱和缺陷》这本书中的代码 (*(void(*)())0)() //第一段
//(*(void(*)())0)()
/*在这段代码当中
* 第一步void(*)()这个是函数指针的类型
* 第二步(void(*)())0----这个是对0的强制类型转换使0转换成函数指针类型
* 第三步*(void(*)())0)()----是一个指针
*/
第二段
第二段
void (*signal(int, void(*)(int)))(int);
第一步signal是一个函数名
第二步函数名后面的(int, void(*)(int))是函数参数
第三步整个又是一个函数指针参数类型是int
typedef关键字
typedef是关键字没在C语言当中可以起到重命名的作用 typedef int* unit;
typedef void(*ptr)(int);
typedef void(*deff)();
函数指针数组
我们之前学了指针数组同理函数指针数组是将函数指针放入数组当中那么这个该怎么实现呢 //函数指针数组 void (*)()ptr[10] ;
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909783.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!