【C语言】:

操作符(https://mp.csdn.net/editor/html/115218055)

数据类型(https://mp.csdn.net/editor/html/115219664)

自定义类型:结构体、枚举、联合(https://mp.csdn.net/editor/html/115373785)

变量、常量(https://mp.csdn.net/editor/html/115230188)

分支、循环语句(https://mp.csdn.net/editor/html/115234118)

字符串+转义字符+注释(https://mp.csdn.net/editor/html/115231391)

指针(https://mp.csdn.net/editor/html/115281303)

数组(https://mp.csdn.net/editor/html/115266750)

函数(https://mp.csdn.net/editor/html/115265396)

内容来自   B站  C语言教学视频   https://www.bilibili.com/video/BV1RX4y1u7Zh

指针

1. 指针是什么

2. 指针和指针类型

3. 野指针

4. 指针运算

5. 指针和数组

6. 二级指针

7. 指针数组

8.数组指针:

9.数组参数、指针参数

10.函数指针:

11.函数指针数组:


1. 指针是什么

指针是什么?
在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向
(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以
说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址
的内存单元。
指针是个变量,存放内存单元的地址(编号)。
#include <stdio.h>
int main()
{int a = 10;//在内存中开辟一块空间int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。//将a的地址存放在p变量中,p就是一个之指针变量。return 0;
}
总结:指针就是变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)。
指针是用来存放地址的,地址是唯一标示一块地址空间的。
指针的大小在32位平台是4个字节,在64位平台是8个字节

2. 指针和指针类型

char* 类型的指针是为了存放 char 类型变 量的地址。 short* 类型的指针是为了存放 short 类型变量的地址。 int* 类型的指针是为了存放 int 类型变量的地址。
char  *pc = NULL;
int   *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;
总结:指针的类型决定了指针向前或者向后走一步有多大(距离)。
#include <stdio.h>
//演示实例
int main()
{int n = 0x10;int* pi = &n;printf("%p\n", pi);//  00CBFAF8printf("%p\n", pi + 1);// 00CBFAFCreturn 0;
}int *P; p+1  --> 4cah*p; p+1  --> 1

总结: 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。 比如: char* 的
指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。
指针类型决定了指针进行解引用操作的时候,能够访问空间大小int* p;  *p能够访问4个字节cahr* p;  *p能够访问1个字节double* p; *p能够访问8个字节

3. 野指针

概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

1. 指针未初始化

#include <stdio.h>
int main()
{int* p;//局部变量指针未初始化,默认为随机值*p = 20;return 0;
}

2. 指针越界访问

#include <stdio.h>
int main()
{int arr[10] = {0};int *p = arr;int i = 0;for(i=0; i<=11; i++){//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;}return 0;
}
3. 指针指向的空间释放
 #include <stdio.h>int * test(){int a = 10;return &a;}int main(){int*p = test();return 0;}
如何规避野指针
1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放即使置NULL
4. 指针使用之前检查有效性

4. 指针运算

指针 +- 整数

#include <stdio.h>
//用指针的方式打印数组元素
int main()
{int arr[4] = { 1,2,3,4 };int sz = sizeof(arr) / sizeof(arr[0]);int* p = arr;int i = 0;for (i = 0; i < sz; i++){printf("%d ", *p); p += 1;}return 0;
}

5. 指针和数组

数组名表示的是数组首元素的地址

1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。

2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。除此1,2两种情况之外,所有的数组名都表示数组首元素的地址。

int main()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };int *p = arr; //指针存放数组首元素的地址int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i<sz; i++){printf("%d ", *(p + i));}return 0;
}

6. 二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里? 这就是 二级指针 。

    int a = 1;int* pa = &a;int** ppa = &pa;
*ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .
int b = 20; *ppa = &b;//等价于 pa = &b;**ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a .
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

7. 指针数组

#include <stdio.h>
int main()
{int a = 1;int b = 2;int c = 3;int* arr[3] = { &a,&b, &c };int i = 0;for (i = 0; i < 3; i++){printf("%d", *(arr[i]) );}return 0;
}

指针数组的使用:

8.数组指针:

                           

数组指针的使用  :

     

       

            

了解了指针数组和数组指针我们来一起回顾并看看下面代码的意思:
int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];

9.数组参数、指针参数

一维数组传参: 参数部分可以写成数组或指针

#include <stdio.h>
void test(int arr[])
{}
void test(int arr[10])
{}
void test(int *arr)
{}
void test2(int *arr[20])
{}
void test2(int **arr)
{}
int main()
{int arr[10] = {0};  // 一维整形数组int *arr2[20] = {0};  //一维整形指针数组test(arr);test2(arr2);
}

二维数组传参:参数部分可以写成数组或指针

//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。

void test(int arr[3][5])//ok? 可以
{}
void test(int arr[][])//ok?  不行
{}
void test(int arr[][5])//ok? 可以
{}
//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
//这样才方便运算。
void test(int *arr)//ok?  参数为整形指针  错误
{}
void test(int* arr[5])//ok? 参数为整形指针数组  错误
{}
void test(int (*arr)[5])//ok?  此时为指针,指向的是一个含5的int元素的一维数组  正确
{}
void test(int **arr)//ok? 此时是二维指针,应存放一维指针地址,此时需要的是二维数组的指针 错误
{}
int main()
{int arr[3][5] = {0}; //此二维数组可以看作,三个一维数组,所以此二维数组的首元素是 一行5列的 一维数组,指针传参的时候也是要传收割一维数组的地址test(arr);
}

思考: 当一个函数的参数部分为一级指针的时候,函数能接收什么参数?
void test1(int *p)
{}
//test1函数能接收什么参数?    1.取地址    2.指针变量
void test2(char* p )                                                                                
{}
//test2函数能接收什么参数?   1.取地址    2.指针变量                             

二级指针传参
#include <stdio.h>
void test(int** ptr)
{printf("num = %d\n", **ptr);
}
int main()
{int n = 10;int*p = &n;int **pp = &p;test(pp);test(&p);return 0;}
思考: 当函数的参数为二级指针的时候,可以接收什么参数?

void test(char **p)
{}
int main()
{char c = 'b';char*pc = &c;char**ppc = &pc;char* arr[10];test(&pc);test(ppc);test(arr);//Ok?return 0;
}

10.函数指针:

函数指针:指向函数的指针-存放函数地址的指针

int Add(int x, int y)
{int z = 0;z = x + y;return z;
}int main()
{int a = 1, b = 2;// &函数名  和  函数名   都是函数的地址 int (*p)(int, int) = Add;//函数地址在解引用时 可以不需要 * ; 此时的 * 没有意义,printf("%d\n", p(3, 2)); //5printf("%d\n", (*p)(3, 2)); //5 printf("%d\n", (**p)(3, 2)); //5printf("%d\n", Add(3, 2)); //5//  printf("%d\n", *p(3, 2)); //错误写法return 0;
}

//代码1
        (*(void (*)())0)();
//代码2
  void (*signal(int , void(*)(int)))(int);
    

 11.函数指针数组:

那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?

int (*parr1[10]])();
int *parr2[10]();
int (*)() parr3[10];答案是:parr1 parr1 先和 [] 结合,说明parr1是数组,数组的内容是什么呢? 是 int (*)() 类型的
函数指针。

  

12.回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一
个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该
函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或
条件进行响应。

【C语言】-- 指针相关推荐

  1. c语言获取指针分配的字节数,c语言指针知识点总结(共6篇).docx

    c语言指针知识点总结(共6篇) C语言指针教学中的知识点分析与总结 摘要:分析指针的基本概念及指针在数组.函数.字符串.动态存储分配等方面的应用,提出指针教学过程中易混淆概念及注意事项,对初学者深入理 ...

  2. C语言指针数组与数组指针的区别

    C语言指针数组与数组指针的区别 首先,顾名思义 数组指针是一个指针,是指向一个数组的指针,如 int (a*)[5]:这就是一个指向含有5个元素的数组的指针 指针数组是一个数组,它包含的元素全是指针变 ...

  3. simple c语言,C语言——指针(simple).ppt

    C语言--指针(simple) 莆田学院计算机教研室 2003年5月 指 针 绍兴文理学院自动化教研室 2011年4月 本讲主要内容 指针概述 地址· 指针· 指针变量 指针变量作为函数参数 指针与数 ...

  4. c语言115写成16进制,C语言指针问题

    C语言指针问题 來源:互聯網  2009-04-01 16:01:29  評論 分類: 電腦/網絡 >> 程序設計 >> 其他編程語言 問題描述: int a=115,*p;p ...

  5. C语言指针总结大学霸IT达人

    C语言指针总结大学霸IT达人 C语言的指针是C语言区别其它语言的最主要的特定之一.有了指针,C语言就可以抛开所有束缚,直接对内存中的数据进行操作,这样,不单对数据的操作更加快捷,并且可以高效的利用空间 ...

  6. CPU 以字节为单位编址,而 C 语言指针以指向的数据类型长度作自增和自减。

    切记:CPU 以字节为单位编址,而 C 语言指针以指向的数据类型长度作自增和自减.

  7. c语言 指针函数 详解,[NOTE-C]C语言指针详解(一)

    C语言指针让一切想法变成可能,强转和指针可以看做一项呼风唤雨的利器,但是C语言中指针应用又需要格外的小心,其更灵活的利用内存,因为不当的应用可能引起各种异常,这篇文章就是让我们一起来认识C指针,更好的 ...

  8. c语言指针的相关运算,C语言指针的运算

    本文讨论使用指针进行的运算,最重要的运算是获取指针所引用的对象或函数.也可以比较指针,使用指针来遍历一个内存区域. 使用指针读取与修改对象 间接运算符 * 生成内存中的位置,该位置的地址存储在一个指针 ...

  9. C语言指针和二维数组

    二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有"缝隙".以下面的二维数组 a 为例: int a[3][4] = { {0, 1, 2, ...

  10. c语言首尾指针相同 则,6.C语言指针练习题.doc

    6.C语言指针练习题.doc 一.知识点 1.? 掌握指针.地址.指针类型.空指针(NULL)等概念: 2.? 掌握指针变量的定义和初始化.指针的间接访问.指针的加减运算.指针变量比较运算和指针表达式 ...

最新文章

  1. LeetCode 845. 数组中的最长山脉
  2. c语言中gets函数可以输入空格吗_C语言中printf和gets函数的实用技巧
  3. 跟老杨学java系列(一)前传
  4. hexo的yelee主题使用自定义字体并用字蛛进行字体压缩的sed脚本
  5. svn 修改文件的可执行权限
  6. windows 平台下,运用 Python 进行简单的文件操作需要用到的函数
  7. 实作 ASP.NET 多笔数据离线编辑
  8. ASP.NET Core利用拦截器 IActionFilter实现权限控制
  9. linux如何查看tomcat端口号,如何在Linux中修改tomcat端口号
  10. 达梦数据库存储过程调用
  11. 真正认识 realloc 的工作方式(转载)
  12. U盘、移动硬盘不格式化制作启动盘
  13. 海康大华网络摄像机搜索工具
  14. 个人考研资料整理(更新一战后感想)
  15. Oracle 执行计划详解(预估 + 真实)
  16. 嵌入式软件设计层级划分概念
  17. 致信oa系统服务器ip,OA系统登陆考勤IP控制
  18. 云计算发展趋势都有哪些 如何快速入行云计算
  19. acdream 1201 SuSu's Power dp
  20. linux 路由 pppoe ipv6,ubuntu PPPoE v6 Server配置

热门文章

  1. C#开发斑马RFID打印机zt410
  2. 三种代码生成炫酷代码雨(推荐)
  3. 【直线检测】基于LSD实现直线检测含Matlab源码
  4. linux桌面记事本,推荐6款简单实用的手机记事本APP,总有一款适合你的‖APP展览馆...
  5. MapReduce统计以某字母开头的单词的平均长度
  6. DRL-FlappyBird
  7. 资产证券化为什么需要区块链技术?专访趣链科技揭开“区块链+ABS”迷雾
  8. SpringBoot解决跨域请求的OPTIONS问题
  9. 系统流程图、数据流程图、IPO图 和甘特图
  10. 图书信息管理系统C语言IPO,基于IPO的Python教学设计