08 | 指针系列(二):记住,指针变量也是变量
任务回顾
必知必会,查缺补漏
1. 深入理解:指针变量的类型
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了指针变量的重要概念和与数组的关系。首先,指针变量的类型决定了取值时的字节长度和在加减法运算中的地址长度,而不同类型的指针占用的存储空间大小是相等的。其次,文章介绍了指针变量与数组的关系,指出数组名代表数组的首地址,可以用指针变量来存储,并且通过指针变量和数组名进行加法运算可以达到相同的效果。最后,强调了在编程中,多种等价表示都是有效的,需要重视这些等价表示的学习。整体而言,本文通过深入浅出的方式,帮助读者理解了指针变量的重要概念和与数组的关系,为读者提供了一份技术上的详细指南。
《人人都能学会的编程入门课》,新⼈⾸单¥59
全部留言(22)
- 最新
- 精选
- 徐洲更同样也有@大牛凯一样疑惑,不过不只是针对指针,而是所有数据类型。C语言是如何存放类型信息呢?对于`int a`而言,使用`a="123"`将字符串赋值给整型是会出问题的。这种类型错误的底层原理是啥呢?是不是C语言会划定一些区域,用来存放不同类型的变量呢?
作者回复: 类型信息会被转换成相关的汇编代码。这个当中涉及到两件事情:一个是类型检查,这个是在编译阶段就做完了,另一个就是具体的程序运行,而运行阶段就已经没有了类型信息。也就是说,你所谓的出错,是在编译阶段报的错误。这个问题,你可以往后看,看到预处理命令一节的时候,可能就会认识的更清晰了。
2020-01-2326 - Geek_7c47de老师你好,我有个小问题。 你在本节课中所举例子 0x61626364 为什么指针指向的的第一个字节不是0x61而是0x64呢?
作者回复: 指针也有可能指向0x61,这个跟操作系统有关系,大端系统和小端系统的区别。我们一般的都是小端系统,数字的低位存储在低地址位,所以指针指向0x64。
2020-06-293 - Noya#include <iostream> using namespace std; struct Date { int x, y; } a[2]; int main(void) { struct Date *p = a; printf("%p\n", &a[1].x); printf("%p\n", &(a + 1)->x); // 方法1, 效果和上面一样 printf("%p\n", &(a[0].y) + 1); // 定位到 a[0].y, 然后+1就是a[1].x的地址了 printf("%p\n", &(p + 1)->x); printf("%p\n", &(p->y) + 1); return 0; } 老师 这是我的思路
作者回复: 不错!很棒!能把指针理解运用到这个程度,今后绝大多数和指针相关的问题,你基本就都可以自己理解和解决了。d(^_^o)
2020-05-0323 - 罗耀龙@坐忘茶艺师学编程 老师,在我windows DEV环境里,写 int a , *p = &a; char *q = &a; 提示错误,说是int型与char型用在a上有冲突。
作者回复: 这个和编程环境没关系,主要是&a 返回的地址类型和指针类型不匹配导致的。你进行强制类型转换就好了。语法类似于: char *q=(char *)&a; 这样就把 int *类型的地址,转换成了 char *类型的地址
2020-05-1952 - rocedu把内存抽象成字节数组,上面内容就更容易理解了,总结的真好!
作者回复: ^_^
2020-02-102 - LJK老师好,请教一个问题,所有指针如果都是无差别存储地址的话,那拿到一个指针如何判断它的类型呢?整数型和字符型指针中,“整数”和“字符”这两个类型是存放在哪的呢?
作者回复: 这个信息已经转换成了相关的汇编代码,你想想,指针的类型是不是只有在加减运算和取值操作的时候有用?那么转换成汇编的时候,只需要对这两个操作,做针对性的转换即可。
2020-01-2322 - Jackie关于变量类型的区分,我的理解是在代码里声明了int a之后,编译的词法分析阶段会查表,把int对应的4这个大小对源码做转换,比如对一个int *p变量来说,p+1的源码,编译后会变成p的地址加上1*4这里的1是源码里p+1的1,4是int类型查表得到的4,关于类型的静态检查,这样理解对吗?
作者回复: 完全正确!程序一旦编译完成以后,就没有了类型的概念。
2020-06-201 - 三件事int main(int argc, char const *argv[]) { int i = 0; int arr[3] = {0}; for (; i <= 3; i++) { arr[i] = 0; printf("Hello world\n"); } return 0; } 老师,这是之前在争哥的数据结构之美中遇到的一个问题,说是 printf 会被执行无数次,原因是数组越界后,c 可以访问任意的内存地址。但在这个例子里,arr[i] 越界后又正好访问到 i = 0 的地址,所以会无限循环。 我自己试了下,并没有出现循环,而是打印了四次之后就中断了。 libsystem_kernel.dylib`__pthread_kill: 0x7fff64f437f0 <+0>: movl $0x2000148, %eax ; imm = 0x2000148 0x7fff64f437f5 <+5>: movq %rcx, %r10 0x7fff64f437f8 <+8>: syscall -> 0x7fff64f437fa <+10>: jae 0x7fff64f43804 ; <+20> 0x7fff64f437fc <+12>: movq %rax, %rdi 0x7fff64f437ff <+15>: jmp 0x7fff64f3da89 ; cerror_nocancel 0x7fff64f43804 <+20>: retq 0x7fff64f43805 <+21>: nop 0x7fff64f43806 <+22>: nop 0x7fff64f43807 <+23>: nop 所以请问下老师,数组越界后内存到底是怎么访问的?上面这个例子是恰好无限循环了吗?
作者回复: 这个例子不太严谨,越界以后能否访问到i,取决于操作系统中系统栈的增长方向。大多数的操作系统中,确实会死循环,在某些版本的操作系统中,这个程序就不会死循环。 数字越界后,还是正常的访问,没啥特殊的。arr[1]就是从数组的首地址向后跳跃1个元素长度所到的元素位置,arr[100]就是跳跃100个元素长度。具体跳到哪里,根据指针的加法运算规则计算即可,你可以先往后看完指针相关知识以后再回来理解你说的这个问题。否则,很难跟你解释。(。ì _ í。)
2020-04-151 - 1043不管你住大别墅还是我住小茅屋,写信邮寄的地址格式和信封标准是一样规范的;在Windows系统里一个执行程序还是一个文件所建的快捷方式都是1kB,不管源文件大有多大、是什么类型。需要多理解的是等价表示,理解的等价表示方法越广泛越有深度对他人的表示方法兼容性就越强。兼容性强不管是维护他人的代码还是领导他人做事,都很容易建立权力影响关系。
作者回复: d(^_^o)
2020-04-051 - 郑江北老师,我有个疑问,由于我是半路出家的,我自学的java了解java里面的变量,C中这个指针变量的作用是什么我一直有疑惑,比如定义一个int型变量a,那么我用变量名就可以做到赋值和取值,为什么要去用指针呢?还是说指针是存储的内存地址更直接一些,或者说更高效一些呢?
作者回复: 不是效率问题,而是功能问题,很多功能实现,传统的变量无法做到,需要依靠在处理过程中传递变量原本的地址才能做到。
2020-03-171