前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你必须知道的指针基础-2.指针的声明和使用及数组和指针的关系

你必须知道的指针基础-2.指针的声明和使用及数组和指针的关系

作者头像
Edison Zhou
发布2018-08-20 16:13:58
1K1
发布2018-08-20 16:13:58
举报
文章被收录于专栏:EdisonTalkEdisonTalk

一、计算机知道数据类型吗?

1.1 神奇的数据类型

  At first,计算机中绝大部分数据都放到内存中的,不同的数据放到不同的内存区域中。But,内存角度没有数据类型,只有二进制;数据以字节(8位二进制)为单位存取。不同数据类型占据不同的字节,例如在32位系统中:int 为4个字节,short为2个字节(下面如未特殊声明,均为32为系统环境下的说明)。下面我们看看int类型、short类型和double类型的数字分别在内存中如何存储:

  ①int类型:99999

  由于int类型占4个字节,每个字节8位,所以在内存中会有如上图所示的四个字节来存储99999的二进制。其中,0001~0004是内存中的编号。为了验证,我们可以通过科学计算器来将99999转换为二进制看看:

  由于int类型在内存占四个字节,每个字节8位,那么一共应该有32位。所以,可以看到内存编号0001中是自动补充的0,而0002中则补充了7个0。后面0003和0004则是转换后的二进制数。验证结束,发现跟上图所示的一模一样。

  ②short类型:8888

  由于short类型只占2个字节,所以在内存中会有如上图所示的两个字节来存储8888的二进制。

  ③long类型:9999

  由于long类型占8个字节,所以内存中会出现8个字节来存储9999的二进制。

PS:由于内存只管存储,不知道数据类型,所以我们可以知道,所谓的数据类型都是程序语言编译器在识别和标注。也就是我们所说的,要取几个字节,从哪里开始到哪里结束,都是编译器在帮我们做,内存是不管的。

1.2 C程序中神奇的&

  假如有下面一段代码,声明了两个int类型的整数,其中&i表示:获得变量i所指向内存的地址,地址也是数字。

代码语言:javascript
复制
int i = 5;
printf("%d\n",&i);

int j = 5;
printf("%d\n",&j);

  那么,我们可以通过程序输出的结果来验证在内存中的地址是否是一个数字,以及是否满足上面所说的字节长度:

  可以看出,两个int类型的变量的内存地址的确是数字,并且相差4个字节。(这里要说明的是在堆栈中,内存地址的分配是从高位到低位,所以这里第一个变量的内存地址比第二个变量的内存地址的数字要高)

PS:在.NET中,数据类型分为值类型和引用类型。其中,值类型被分配在栈上,引用类型被分配在堆(托管堆)上。 (1)栈高效而灵活,并且可以自动销毁变量,回收空间,但对于处理大容量的数据还是不够; (2)堆可以存储大容量的数据,但是无法自动回收内存,需要借助于GC(垃圾回收机制)来实现,于是也就有了.NET中的托管堆。

  既然&是取地址,那么就可以用int类型存储指针地址:

代码语言:javascript
复制
int j=5;
printf("%d\n",&j);

int iAddr = &j;
printf("%d\n",iAddr);

  查看结果后会发现,iAddr也会显示地址。其实,short、long、char等的地址都可以用int表示。But,如果用int表示各种指针,那么就不知道内存中到底放的是什么类型(其实内存中也不知道是什么类型,都是一堆字节数据而已)。所以,也就有了指针,在实际中一般用“类型指针”来表示,其结果是一样的。

代码语言:javascript
复制
int *iPtr = &i; 
printf("%d\n",iPtr);

二、指针的声明与使用

2.1 神奇的*号

  (1)声明

  在C中,可以用*号来声明一个指针,通常都是用具体要指向的类型的指针来指向目的变量。这样的指针就叫做“类型指针”,也就使程序语言知道要从内存中取几个字节了。

代码语言:javascript
复制
int i = 5;
int* iPtr = &i; // 类型化的指针,知道是从内存中取几个字节
printf("%d\n",iPtr);
int i1 = *iPtr;
printf("i1=%d\n",i1); // 取iPtr指针指向的内存中的数据

  (2)使用

  可以使用*取指针指向的内存数据,如上面代码中的 i1 = *iPtr。下面来看看代码的运行结果:

  还可以通过指针修改变量的值,例如我们可以写以下代码操作iPtr指针来修改i的值:

代码语言:javascript
复制
*iPtr = 100;
printf("i=%d\n",i);

  这下i的值也变成了100。(可以理解为把100存入到iPtr所指向的内存中)

2.2 小结

*的两个用途: (1)声明的时候用来声明指针变量: int *iPtr; (2)除了声明变量的时候,其他时候*用来表示获取指针指向的数据。 &用来获取变量的地址。

三、数组和指针

3.1 一块连续的内存区域

  我们经常听说:数组在内存中是一块连续的内存区域,那么来验证一下,声明一个数组,并依此输出其内存地址:

代码语言:javascript
复制
int nums[] = {33,55,66,77,88};
for(int i=0;i<5;i++)
{
    printf("%d\n",&(nums[i]));
}

  输出结果如下图所示:可以看出,各个内存地址数字均只差4个字节,是连续的。

3.2 指针如何指向数组

  在开发中一般使用第二种方式,即数组元素的名字即是数组第0个元素的内存地址。

代码语言:javascript
复制
int* iptr1 = &(nums[0]); //获取第0个元素的内存地址
int* iptr2 = nums; //一般这样用,数组元素的名字就是“第0个元素的内存地址”

3.3 字符串即字符数组

  在计算机中没有字符串的概念,都是用字符数组在表示字符串。因此,字符串也就是“以\0结尾的一段连续的char内存区域”。

代码语言:javascript
复制
    char  str1[] = "helloedison";
    char* str2 = str1;
    printf("str1=%c\n",str1[0]);
    printf("str2=%c\n",*str2);

  可以看到,使用指针str2指向了str1的第0个元素的地址,输出结果验证了一致性:

参考资料

  如鹏网,《C语言也能干大事(第三版)》

作者:周旭龙

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-07-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、计算机知道数据类型吗?
    • 1.1 神奇的数据类型
      • 1.2 C程序中神奇的&
      • 二、指针的声明与使用
        • 2.1 神奇的*号
          • 2.2 小结
          • 三、数组和指针
            • 3.1 一块连续的内存区域
              • 3.2 指针如何指向数组
                • 3.3 字符串即字符数组
                • 参考资料
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档