指针的进阶(一)目录:

  • 字符指针
  • 数组指针和指针数组
  • 函数指针

字符指针

在开始讲解这一章节之前,我们需要了解指针前面声明的类型的意义

类型 * 指针名

对于指针来说,我们在给指针进行声明时,我们声明的类型并不是指针的类型,而是指针所指向的地址的类型,也就是指针看待这段地址的方式,它该如何读取数据,它如果加一该移动多少位,只有了解了这个才能方便理解下面的内容

我们首先来说的就是字符指针char*

一般我们是这样运用字符指针的

 char a = 'a';char* p = &a;

但是我们还能以这种方式运用

 char*str = "hello world";

这时候,经常就会有初学者以为我们的指针指向的是hello world这个字符串,但其实这里只是把字符串的首元素的地址保存到了这个指针当中。

同时我们还需要理解这样的指针与字符串的区别。

例如:

 char str1[] = "hello";char *str2 = "world";

这里的str1是在栈上开辟一块内存空间来存放hello这段字符,而这里的str2是用指针指向常量区的‘’world‘’这段字符,所以我们无法给str2进行赋值与修改,因为常量是不可改变的,我们也无法将这str1与str2进行比较,因为他们是本质不同的两样东西。
借此,在引申一个小内容

 #include<stdio.h>
int main()
{char str1[] = "helloworld.";char str2[] = "helloworld.";char* str3 = "helloworld.";char* str4 = "helloworld.";if(str1 == str2)printf("1\n");elseprintf("0\n"); if(str3 == str4)printf("1\n");elseprintf("0\n"); return 0;
}


为什么在这里,str1与str2不同呢?
因为我们给字符串赋值时,是在栈上面开辟一个内存空间,来给这个字符串存放一个数值,虽然他们存放的内容是一样的,但是它们存放在不同的内存块中,所以进行比较的时候是不同的
那为什么str3和str4是相同的呢?
因为它们是字符指针,它们指向的都是常量区中的hello world这段字符,它们指向的内容一样,所以它们相同。
这也就是为什么我们在进行字符串的比较的时候运用的都是strcmp这个函数的原因。


数组指针和指针数组

在我刚刚接触指针的时候,我经常会搞混两个东西,一个是数组指针,一个是指针数组,因为它们太过相似,但如果你了解了运算符的优先级以及我之前说的指针如何看待类型,你就会很快的区分它们

上图中的两个指针是不是特别相似?那我们如何区分呢?

首先,我们先看几个运算符的优先级对于p1,[] 的优先级是很明显高于 *的,所以它的本质就应该是一个数组,而剩下的int *就应该是它所存放的数据类型,所以它是一个存放指针元素的数组,即指针数组。
而对于p2,它的()的优先级是很明显高于 [] 的,所以我们应该先去考虑括号中的内容,括号中是一个指针 *,所以它的本质就应该是一个指针,而剩下的就是它所指向的地址的类型,所以它是一个指向数组的指针,即数组指针。

如果我们要了解一个数组指针是如何作用的,我们首先要了解这样一个知识点。

对于一个数组,它的数组名和&数组名有什么区别。
我们都知道数组名是这个数组的首元素的地址,但是&数组名却不是很了解。

int main()
{int arr[10] = {0};printf("%p",arr);printf("%p",&arr);return 0;
}


我们查看它们的地址,却完全的一样,那是不是证明它们相同呢?

int main()
{int arr[10] = {0};printf("%p",arr+1);printf("%p",&arr+1);return 0;
}

其实不是,我们再给它们分别+1

这里区别就显现出来了,arr+1加的只是一个元素的大小,而&arr+1加了一整个数组的大小。
所以我们就能了解,&arr指向的是这一整个数组的地址。
而我们的数组指针,是一个指向数组地址的指针,所以数组指针应该这样指向一个数组。

 int (*p)[10] = &arr;

函数指针

在了解函数指针前我们要先了解一个小的误区


这两个哪一个才是函数指针呢?
还是之前判断数组指针的那个方法,我们看优先级,先看括号,它是一个指针,剩下的就是它所指向的类型,一个返回值为void的函数。
而第二个其实就是一个函数的声明,声明一个返回值为void*的函数

我们该如何调用这个函数指针呢?

无论是直接调用还是进行解引用后调用,我们都可以直接使用这个函数

#include<stdio.h>void print()
{printf("1\n");
}int main()
{void (*p)();p = print;p();(*p)();return 0;
}


在使用函数指针的时候,因为函数的特殊性,在很多情况下代码的可读性会十分差,如下面这段代码。

 void(*signal(int,void(*)(int)))(int);



这是它的参数类型

这是它的函数名
外面剩下的则是它的返回类型。
所以它是一个参数为int 和函数指针的一个函数,返回值为函数指针。
这样的代码让人很难理解。
那该如何简化呢?我们可以用typedef进行简化

 typedef void(*p)();

简化完后

这样我们的代码可读性就大大的提升了。

第一部分就讲到这里吧

C语言程序设计 | 指针的进阶(一):字符指针、数组指针、指针数组、函数指针相关推荐

  1. 何钦铭c语言程序设计第八章,c语言程序设计(第3版)何钦铭-颜-晖-第8章--指针

    1.第8章 指针[练习8-1]如果有定义"int m, n = 5, *p = &m;"与m = n等价的语句是 B .A m = *p; B. *p = *&n; ...

  2. 何钦铭c语言程序设计第八章,C语言程序设计(第3版)何钦铭颜晖第8章指针

    <C语言程序设计(第3版)何钦铭颜晖第8章指针>由会员分享,可在线阅读,更多相关<C语言程序设计(第3版)何钦铭颜晖第8章指针(16页珍藏版)>请在人人文库网上搜索. 1.第8 ...

  3. c语言程序设计一维数组教案,《C语言程序设计》-任正云-电子教案 第7章数组

    1.第七章 数组,The C Programming Language Chapter 7 Arrays,构造数据类型; 有序数据的集合; 可以看成是具有相同名字不同下标的同一数据类型的简单变量的集合 ...

  4. c c++ 函数内数组初值_C/C++函数指针与指针函数

    关于指针,前面文章C语言指针详解有过介绍,这里主要讨论函数指针和指针函数. 1 什么是指针? 定义:指针是程序数据在内存中的地址,而指针变量是用来保存这些地址的变量; 上面一个 4GB 的内存可以存放 ...

  5. 【C语言进阶深度学习记录】三十二 函数指针与使用函数指针实现回调函数

    回调函数是非常重要的概念 文章目录 1 函数的类型 2 函数指针 2.1 函数指针的使用 2.2 使用函数指针实现回调函数 3 总结 1 函数的类型 跟以前学数组的时候是一样的,C语言中的数组是有自己 ...

  6. c语言指针和函数对数组A升序排序,函数指针作为函数參数,实现冒泡排序的升序排序和降序排序...

    #include #define N 10//定义数组元素个数 int Ascending(int a,int b);//升序排列的函数声明 int Descending(int a,int b);/ ...

  7. C语言程序设计第五版谭浩强著 第8章291-292指针系列

    1.输入3个整数,按由小到大的顺序输出. #include<stdio.h> main() {int a,b,c,*p1,*p2,*p3;p1=&a;p2=&b;p3=&a ...

  8. 【C 语言】文件操作 ( 按照单个字符的方式读写文件 | fgetc 函数 | fputc 函数 )

    文章目录 一.文件名路径设置 二.文件打开方式 三.fputc 函数 | 按照字符方式写文件 1.fputc 函数 2.代码示例 四.fgetc 函数 | 按照字符方式读文件 1.fgetc 函数 2 ...

  9. c语言通过指针变量输出10个元素,C语言程序设计第2版指针程序设计(10页)-原创力文档...

    C 语言程序设计 - 理论方法与实践(第 2 版) 7.4.1 简单指针变量作函数参数 例 7-9 用比较交换法 ,将一维数组的最 大值移到数组的最 末元素位置,交换 过程用上述 swap() 函数实 ...

  10. c语言程序设计 指针 .ppt,C语言程序设计 指针.ppt

    C语言程序设计 指针.ppt 第6章 指 针,C 语言程序设计,北京科技大学 计算机系,2018/8/156.1 概述6.2 指针和指针变量6.3 指针与数组6.4 指针和函数6.5 动态存储分配,第 ...

最新文章

  1. python怎么安装requests库-Python3.6安装及引入Requests库的实现方法
  2. android studio编译提示错误:android Error:(21, 19) 错误: 程序包R不存在
  3. ubuntu 运行c++_06_Linux下VSCode简单编程(远程开发WSL_Ubuntu_18.04) | C语言入门
  4. Eclipse常用快捷
  5. 一个基于Python2.7的智慧校园系统
  6. hashmap,hashTable concurrentHashMap 是否为线程安全,区别,如何实现的
  7. 日本的电视节目到底能有多特别?
  8. Hibernate问题浅析
  9. 苏宁国美盈利报警:线下乏力线上重金加码
  10. 构建azure对话机器人_如何在5分钟内使用Azure创建聊天机器人
  11. java 普通方法_Java普通方法与static方法的多态
  12. 压力测试工具Siege详解
  13. jpg转换成mobi电子书
  14. CentOS7 WordPress无法将上传的文件移动至wp-content/uploads/ ApacheNginx解决方案
  15. Java线程池工作原理
  16. 屏蔽百度搜索右边的热点和广告推广
  17. iptables 删除规则
  18. 推荐一款手机、电脑必备的效率工具,功能强大,支持所有平台
  19. mmdetection安装教程 | 踩坑总结
  20. 中国大学MOOC C语言程序设计(大连理工大学) 课后编程题 第十一周题解(个人向仅供参考)

热门文章

  1. SpringBoot高级-缓存-搭建redis环境测试
  2. oracle exp 二进制,Oracle备份之exp自动逻辑备份(二)
  3. 我的世界服务器修改成创造,我的世界怎么创建领域
  4. java cmd找不到文件_cmd中输入java找不到文件解决方法
  5. Maven 配置文件 POM 的常用依赖配置代码
  6. 字符之间或者结构体之间比较
  7. Win8Metro(C#)数字图像处理--2.33图像非线性变换
  8. 微信小程序图片上传(文字识别)
  9. Prism Training Kit 4.0
  10. 沟通CTBS助六和集团实现财务集中管理