所谓指针,本质就是标识内存中某个位置的数据

在日常学习中,我们需要了解的只是:

  1. 内存中每个位置都是由独一无二的地址标识
  2. 内存中的每个位置都包含一个值

基本概念

运算符 ‘*’

通过指针访问指向的值的过程称为间接访问(indirection)或者叫做解引用指针(dereferencing the pointer),执行间接访问的操作符就是单目运算符’*’

这里一定要注意,在变量声明时使用的’’,与解引用时使用的’'有着本质上的区别,不可以将二者作用混淆

int a = 50;
int* b = &a;
//这里的'*'主要起声明的作用,告知程序当前变量b是一个指针型变量
printf("%d",*b);
//这里的'*'是单目运算符,对指针型变量b执行取值操作

编写程序过程中我们往往会定义诸多的变量名实现对值的操控,在这个过程中,变量名与内存地址的关联并不是硬件提供的,它是由编译器为我们实现的,所有这些变量名给了我们一种更方便的方法记住地址,但是–++硬件仍然通过地址来访问内存位置++

#include<stdio.h>int main() {int a = 50;  //a的本质是值int* b = &a;  //b的本质是指针变量printf("b=%d\n", b);  //这里直接打印出b的值//b作为一个指针变量,直接打印出来的就是a的内存地址,而不是a的值printf("*b=%d\n", *b);  //对b表示的内存地址进行*操作(取值操作)//利用地址取值后,得到的就是存储于这个地址的a的值printf("&b=%d\n", &b);  //对b变量进行取地址操作//b虽然是存储地址,但其作为指针变量,本质还是变量//变量就必然需要内存来存储,也必然有自己的内存地址//所以,取地址后的数据其实就是b的内存地址
}

运行结果

b=17824784
*b=50
&b=17824772

未初始化和非法的指针

int main() {int* a ;*a = 50;/*上述程序看起来符合逻辑,但实际上是十分严重的错误*我们并没有对a指针进行初始化,所以它所指向的地址是未知的*一般情况下,a的初始值会是一个非法地址,进而在程序执行过程中*Windows出现一般保护性异常阻止程序继续进行*最坏情况可能导致a指向一个合法的地址,进而修改合法地址内的值*造成严重错误,且不容易被察觉*/return 0;
}

NULL指针

NULL作为一个特殊的指针变量,表示不指向任何地址

int main() {int* a = NULL;if (a == 0) {printf("True\n");}else {printf("False\n");}return 0;
}

观察上述程序不难发现,在程序编译过程中,NULL指针和0值是完全等价的,这是一种基于源代码的约定,有助于我们测试一个指针变量是否为NULL ,而NULL指针的实际值不一定是0

对一个NULL指针进行解引用操作是违法的,因为NULL指针并没有指向任何内容,所以在对指针进行解引用之前,必须要确定指针是否为空

指针变量可以作为左值也可以做为右值

int a=10;
int* b=&a;
*b=20-*b;
b=20-*b;

上述第三条语句是合法的,第一个表示取到该内存地址内的变量,对它进行重新赋值,第二个表示,取出该内存地址内变量的值,利用值进行计算

第四条语句是非法的,指针变量不能直接作为左值进行赋值操作(K&R C)

指针的指针

int a=50;
int* b=&a;
int** c=&b;

利用指针获取字符串长度

int MyStrLen(char* str) {int length = 0;//依次访问字符串内容,直到遇到NUL终止符while (*str++ != '\0') {length++;}return length;
}int main()
{char* str = "HelloWorld";int len = MyStrLen(str);printf("%s\nlength=%d\n", str, len);return 0;
}

指针与数组

利用指针遍历数组

#include<stdio.h>
void main() {int score[7] = { 95,89,56,78,45,59,77 };int sum = 0;int* p1;for (p1 = score; p1 < &(score[7]); p1++) {  //这里第一个位置还可以用p1=&(score[0])printf("%d\n", *p1);}
}

ps:数组名就是数组首位元素的地址

指针运算

int main()
{int* p[5] = { 1,2,3,4,5 };int* num = &p[0];int* pnum = num + 2;ptrdiff_t n = (pnum + 1) - num;  //两个指针变量之间做差,得到结果是一种有符号整型//表示两个指针在内存中的距离(以数组元素长度为单位,而不是字节长度)printf("*num=%d,*pnum=%d\n", *num, *pnum);printf("(pnum+1)-num=%d\n", n);return 0;
}

注意:上述指针之间相减求距离的前提是位于同一个数组内,否则结果无意义

PS:同一个数组内的指针可以进行’<’,’<=’,’>’,’>='运算,此类比较表达式可以对指针在数组中的位置做出比较

运算结果

*num=1,*pnum=3
(pnum+1)-num=3

除了NULL指针外,再也没有任何内建的记法用来表示指针常量,因为程序员通常无法预测编译器会把变量放到内存中哪个位置,当出现极特殊情况我们需要自定义指针常量时,一般采取将整形数据强制类型转换为指针常量的方式

[C语言]-指针详解相关推荐

  1. c语言的指针详解ppt,最全的C语言指针详解.ppt

    最全的C语言指针详解.ppt 第6章 指针,6.1 指针定义与使用 6.2 指针与函数 6.3 指针与数组 6.4 指针与字符串 6.5 指针数组与多级指针 6.6 指针与动态内存分配 6.7 指针的 ...

  2. C语言指针详解(全解)—— 前篇

    关于指针的基本概念及相关运算写在了上一篇博客 C语言指针详解(初级)_Seinrich的博客-CSDN博客 本篇博客来详细的解说一下指针,深入探讨指针 一.指针与const const修饰的变量为常变 ...

  3. C语言指针详解——入门C语言指针,初级指针使用。

    原文地址:我的个人博客点击查看 C语言教程第二弹--指针详解 所有学过C语言的人都知道,C语言难在它的指针的使用和理解,今天,我带给大家C语言的指针的教程,供大家学习交流,如果有讲的不对的地方,请给作 ...

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

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

  5. c语言 指针_C 语言指针详解

    (给CPP开发者加星标,提升C/C++技能) 作者:C语言与CPP编程 / 自成一派123(本文来自作者投稿) 1为什么使用指针 假如我们定义了 char a='A' ,当需要使用 'A' 时,除了直 ...

  6. c语言高低位拷贝_C语言指针详解

    1为什么使用指针 假如我们定义了 char a='A' ,当需要使用 'A' 时,除了直接调用变量 a ,还可以定义 char *p=&a ,调用 a 的地址,即指向 a 的指针 p ,变量 ...

  7. 导航编程用c语言还是c加加,C语言/C加加大神程序员老司机带你玩转C语言指针详解...

    很多初学编程的小伙伴都会选择C语言作为第一门学习的编程语言,因为C语言作为一门底层基础语言相对于其他的高层语言来说更加容易学习.可以来帮助正在学习编程的小伙伴更加快速的了解计算机原理. 但是初学C语言 ...

  8. C语言指针详解(新手入门推荐)

    目录 指针的理解 字符指针:char * 无类型指针void * 指针数组 数组指针 函数指针 回调函数 函数指针数组 练习 指针和数组笔试题解析 指针的理解 关于指针,我先讲一个故事:一个侦探在案发 ...

  9. C语言指针详解——后篇

    目录 一.指针与数组 ​编辑 二.数组传参 2.1一维数组传参 2.2二维数组传参 三.函数指针及应用 四.函数指针数组 一.指针与数组 先来看以下代码及运行的结果 #include <stdi ...

  10. C语言指针详解----指针声明定义赋值

    C语言的指针是让新手很头疼的事情,但是由于其太过于灵活,以至于可以很好得的解决一些复杂的问题,因此不得不掌握.我最近正在学习指针相关的内容,因此在这里做一个小的总结.本篇是不涉及到函数以及结构体等复杂 ...

最新文章

  1. 从底层吃透java内存模型(JMM)、volatile、CAS
  2. php的遍历方法,PHP数组遍历方法总结
  3. js 排列 组合 的一个简单例子
  4. 9999元雷军新宠亮相!机器狗铁蛋,能走能遛能空翻,小米机器人实验室第一款产品...
  5. ttc转ttf在线网站_文件格式怎么在线互转?迅捷PDF转换器告诉你
  6. CSS3制作一个简单的进度条
  7. android builder模式,模式设计(三:Builder模式) (转)
  8. 十大经典排序算法(下)
  9. css文字覆盖线性渐变,利用css使文字渐变
  10. CodeWars刷题笔记
  11. 计算机格式怎么调,怎么改电脑硬盘格式?
  12. [LeetCode-java实现]3. 无重复字符的最长子串
  13. Python — 词汇表(一)
  14. Bazel编译教程(基础篇)
  15. 简单探寻GCC编译器背后的故事
  16. 贴片陶瓷电容器尺寸规格总结
  17. MySQL Java JDBC
  18. mysql @的使用
  19. 【ASP.Net】上传图片+水印
  20. toad mysql导入excel_toad导入表数据库

热门文章

  1. 基于Android的二维码识别系统的研究与实现(eclipse开发)
  2. Meta因数据泄漏被罚1700万欧元 数据安全合规将催生百亿美元市场
  3. Echarst柱状图+饼状图+vue2 商品案例
  4. 第一式、教育基础知识和基本原理
  5. 利用照片名中的日期批量修改照片的修改时间和访问时间(python实现)
  6. NOIP十连测 涂色游戏
  7. NAT ALG和STUN技术
  8. android的优点与不足
  9. kvm linux_在Linux KVM上创建ooRexx构建环境
  10. LeetCode刷题系列