指针变量

地址、指针与引用

烂漫一生 提交于 2020-01-08 09:24:02
  计算机本身是不认识程序中给的变量名,不管我们以何种方式给变量命名,最终都会转化为相应的地址,编译器会生成一些符号常量并且与对应的地址相关联,以达到访问变量的目的。   变量是在内存中用来存储数据以供程序使用,变量主要有两个部分构成:变量名、变量类型,其中变量名对应了一块具体的内存地址,而变量类型则表明该如何翻译内存中存储的二级制数。我们知道不同的类型翻译为二进制的值不同,比如整型是直接通过数学转化、浮点数是采用IEEE的方法、字符则根据ASCII码转化,同样变量类型决定了变量所占的内存大小,以及如何在二进制和变量所表达的真正意义之间转化。而指针变量也是一个变量,在内存中也占空间,不过比较特殊的是它存储的是其他变量的地址。在32位的机器中,每个进程能访问4GB的内存地址空间,所以程序中的地址采用32位二进制数表示,也就是一个整型变量的长度,地址值一般没有负数所以准确的说指针变量的类型应该是unsigned int 即每个指针变量占4个字节。还记得在定义结构体中可以使用该结构体的指针作为成员,但是不能使用该结构的实例作为成员吗?这是因为编译器需要根据各个成员变量的大小分配相关的内存,用该结构体的实例作为成员时,该结构体根本没有定义完整,编译器是不会知道该如何分配内存的,而任何类型的指针都只占4个字节,编译器自然知道如何分配内存。我们在书写指针变量时给定的类型是它所指向的变量的类型

深度解密Go语言之map

自作多情 提交于 2020-01-08 08:51:52
目录 什么是 map 为什么要用 map map 的底层如何实现 map 内存模型 创建 map 哈希函数 key 定位过程 map 的两种 get 操作 如何进行扩容 map 的遍历 map 的赋值 map 的删除 map 进阶 可以边遍历边删除吗 key 可以是 float 型吗? 总结 参考资料 这篇文章主要讲 map 的赋值、删除、查询、扩容的具体执行过程,仍然是从底层的角度展开。结合源码,看完本文一定会彻底明白 map 底层原理。 我要说明的是,这里对 map 的基本用法涉及比较少,我相信可以通过阅读其他入门书籍了解。本文的内容比较深入,但是由于我画了各种图,我相信很容易看懂。 什么是 map 维基百科里这样定义 map: In computer science, an associative array, map, symbol table, or dictionary is an abstract data type composed of a collection of (key, value) pairs, such that each possible key appears at most once in the collection. 简单说明一下:在计算机科学里,被称为相关数组、map、符号表或者字典,是由一组 <key, value>

C语言指针/指向指针的指针

别来无恙 提交于 2020-01-08 04:36:12
先看一段代码: 1 #include <stdio.h> 2 3 int main () 4 { 5 int i = 30; 6 int* pi; 7 int** ppi; 8 9 pi = &i;10 ppi = π11 12 printf("i = %d;\t &i = %d\n", i, &i);13 printf("pi = %d;\t &pi = %d;\t *pi = %d\n", pi, &pi, *pi);14 printf("ppi = %d;\t *ppi = %d;\t &ppi = %d;\t **ppi = %d\n", \15 ppi, *ppi, &ppi, **ppi);16 17 return 0;18 } 执行结果: i = 30; &i = -1013781316 pi = -1013781316; &pi = -1013781328; *pi = 30 ppi = -1013781328; *ppi = -1013781316; &ppi = -1013781336; **ppi = 30 下面用一个简单的图来说明一下: 定义指针类型时,用下面的格式,感觉更容易理解: int *p;    =>   int* p; int **pp;   =>   int** pp; =>右边的写法可以更加明确的看出int*, int**是变量类型,p,

C语言中的强制类型转换

纵然是瞬间 提交于 2020-01-08 04:18:42
C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值。不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个地址就是硬件访问的依据,而名字只是提供给程序员的一种记住这个地址的方便一点的方法。但是,不同的变量在机器中都是0-1代码,所以,我们不能简单的通过检查一个值的位来判断它的类型。 例如,定义如下: int a; float b; double c; long double d; ( 假设它们所占的字节分别是 4 、 8 、 8 、 10 ,而且连续存储于某个地址空间,起始地址是 100 ,则我们可以得到如下内存分布 ) a变量就是由以地址100开始到103结束的4个字节内存空间内的0-1代码组成。b变量则是由以地址104开始到112结束的8个字节内存空间内的0-1代码组成。而在机器中,这些内存都是连续的0-1代码,机器并不知道100~103是整型而104~111是float型,所有这些类型都是编译器告知的。当我们用a时,由于前面把a定义为int型,则编译器知道从a的地址开始向后取4个字节再把它解释成int型。那么(float)a,就是先按照int类型取出该数值,再将该数值按照int to float的规则转换成float型。所以强制类型转换就是按照某个变量的类型取出该变量的值,再按照***to***的规则进行强制转转换。如果是(类型名

C语言指针类型 强制转换

坚强是说给别人听的谎言 提交于 2020-01-08 01:50:40
关于C语言指针类型 强制转换 引用一篇文章: C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值。不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个地址就是硬件访问的依据,而名字只是提供给程序员的一种记住这个地址的方便一点的方法。但是,不同的变量在机器中都是0-1代码,所以,我们不能简单的通过检查一个值的位来判断它的类型。 例如,定义如下: int a; float b; double c; long double d; (假设它们所占的字节分别是 4、 8、 8、 10,而且连续存储于某个地址空间,起始地址是 100,则我们可以得到如下内存分布 ) a变量就是由以地址100开始到103结束的4个字节内存空间内的0-1代码组成。b变量则是由以地址104开始到112结束的8个字节内存空间内的0-1代码组成。而在机器中,这些内存都是连续的0-1代码,机器并不知道100~103是整型而104~111是float型,所有这些类型都是编译器告知的。当我们用a时,由于前面把a定义为int型,则编译器知道从a的地址开始向后取4个字节再把它解释成int型。那么(float)a,就是先按照int类型取出该数值,再将该数值按照int to float的规则转换成float型。所以强制类型转换就是按照某个变量的类型取出该变量的值,再按照***to**

go语言之行--结构体(struct)详解、链表

情到浓时终转凉″ 提交于 2020-01-08 00:55:33
一、struct简介 go语言中没有像类的概念,但是可以通过结构体struct实现oop(面向对象编程)。struct的成员(也叫属性或字段)可以是任何类型,如普通类型、复合类型、函数、map、interface、struct等,所以我们可以理解为go语言中的“类”。 二、struct详解 struct定义 在定义struct成员时候区分大小写,若首字母大写则该成员为公有成员(对外可见),否则是私有成员(对外不可见)。 type struct_variable_type struct { member member_type member member_type ..... member member_type } //示例 type Student struct { name string age int Class string } 声明与初始化 var stu1 Student var stu2 *Student= &Student{} //简写stu2 := &Student{} var stu3 *Student = new(Student) //简写stu3 := new(Student) struct使用 在struct中,无论使用的是指针的方式声明还是普通方式,访问其成员都使用".",在访问的时候编译器会自动把 stu2.name 转为 (*stu2).name。

码农找工作之:秒杀算法面试必须掌握的14种模式

ぃ、小莉子 提交于 2020-01-07 20:38:40
对于茫茫多的程序员来说,准备算法面试简直就是一个亚历山大的过程。看不完的学习资料,更惨的是,很多内容和程序员干的事情感觉相去甚远,这无疑只会雪上加霜。 这样的结果之一就是:程序员需要花上数周的时间在诸如LeetCode这样的在线编程平台上准备刷上几百个面试题目。这些焦虑的程序员都关心类似的问题: 我刷了足够的题了吗?我应该再来点吗? 这就是为啥我专注于帮助码农们掌握每个问题背后的模式的原因:这样的话,你们就不需要苦逼哈哈地担心着茫茫多的(一千多道)LeetCode的进度条了,也帮助你们避免盲目刷题的疲劳。如果你理解这些通用的模式,你就可以把他们当做是模板,去解决其他类似的被改头换面过的题目了。 这篇文章就和大家唠唠所有的面试题目可能的14种模式。当然更重要的,我会给大家讲讲怎么去识别每种模式,每个模式再给大家来几个样题尝尝鲜。当然,这些只是冰山一角啦,详细的,不用多说,墙裂推荐你去看这门课: Grokking the Coding Interview: Patterns for Coding Questions 该课程提供详细的理论讲解,例子和编程训练。 如果你需要买该网址的任何课程,都可以使用coupon code: awesome-developer-20 拿到额外八折。 接下来的这些模式是建立在你已经知晓了数据结构的基础之上的。如果你还没掌握的话,嘿嘿,推荐你去看:

[go]内存对齐

余生长醉 提交于 2020-01-07 18:29:31
参考 参考-校对版 理解类型的本质 当我使用 C/C++ 编写代码时,理解类型(type)是非常有必要的。如果不理解类型,你就会在编译或者运行代码的时候,碰到一大堆麻烦。无论什么语言,类型都涉及到了编程语法的方方面面。 加强对于类型和指针的理解,对于提高编程水平十分关键。 本文会主要讲解类型。 我们首先来看看这几个字节的内存: 内存地址: FFE4 FFE3 FFE2 FFE1 存储的值: 00000000 11001011 01100101 00001010 请问地址 FFE1 上字节的值是多少? 如果你试图回答一个结果,那就是错的。为什么?因为我还没有告诉你这个字节表示什么。(不同类型的含义不同) 回答 10,那么你又错了。为什么?因为当我说这是数字的时候,你认为我是指十进制的数字。 基数(number base): 所有编号系统(numbering system)要发挥作用,都要有一个基(base)。 从你出生的时候开始,人们就教你用基数 10 来数数了。 这可能是因为我们大多数人都有 10 个手指和 10 个脚趾。另外,用基数 10 来进行数学计算也很自然。 基定义了编号系统所包含的符号数。基数 10 会有 10 个不同的符号,用以表示我们可以计量的无限事物。 基数 10 的编号系统为 0、1、2、3、4、5、6、7、8、9。一旦超过了 9,我们需要增加数的长度。 例如

关于指针

天涯浪子 提交于 2020-01-07 12:38:35
关于指针的概念,错误的是:( ) A. 指针是变量,用来存放地址 B. 指针变量中存的有效地址可以唯一指向内存中的一块区域 C. 野指针也可以正常使用 D. 局部指针变量不初始化就是野指针 AC 以下系统中,int类型占几个字节,指针占几个字节,操作系统可以使用的最大内存空间是多大:( ) A.32位下:4,4,2^32 64位下:8,8,2^64 B.32位下:4,4,不限制 64位下:4,8,不限制 C.32位下:4,4,2^32 64位下:4,8,2^64 D.32位下:4,4,2^32 64位下:4,4,2^64 C 写一个函数打印arr数组的内容,不使用数组下标,使用指针。 #include<stdio.h> #include<stdlib.h> int main(void){ int arr[] = {1,2,3,4,5,6,7,8,9,10}; int i; int *p; p = arr; for(i = 0;i<10;i++) { printf("%d",*(p+i)); } system("pause"); return 0; } 下面代码输出的结果是:( ) #include <stdio.h> int main() { int a = 0x11223344; char pc = (char )&a; *pc = 0; printf("%x\n", a);

对指针运算符*文字说明的一点点理解

一笑奈何 提交于 2020-01-07 08:56:22
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 指针运算符称之为间接运算符还称之为取消引用运算符. 间接运算符*可以访问指针所指的变量值(这个文字解释好理解)。 这个运算符也称为取消引用运算符,因为它用于取消对指针的引用。 ”因为它用于取消对指针的引用“(这句话如何更好的理解呢?,自己迷糊了好一阵) 意思是 指针本身也有个地址用于取消对指针本身地址的引用?去引用存储在指针中的地址?可以这样理解吗? 还是 比如 格化式 输出整形 %d *pointer *这里的取消引用运算符 意思是 因为指针本身存储的值是个地址跟要输出的格式化格式不一致 不能输出指针本身存储的值、也就是不输出指针变量中存储的值 (因为存储的是地址),而是输出存储在 指针中的地址中的值,就是引用了存储在指针中的地址的值。 “取消引用运算符,因为它用于取消对指针的引用”单就这句话,是不是就是我理解的这个意思呢. 应该是吧,还会有别的意思吗,应该没有了 认为。 *运算符 不让指针输出它本身存的值(它本身只能存储地址)'而是要输出指针变量中存储的地址中所包含的数据类型值。 来源: oschina 链接: https://my.oschina.net/u/940580/blog/140264