C语言基础及指针②之指针内存分析

续接上篇 C语言基础及指针①

在上一篇中 , 我们了解了C语言的基本语法 , 以及简单指针 , 也知道 , 指针是C语言的核心 , 那么我们今天就来简单剖析一下指针 , 了解他是怎么的神奇 。

今天是七夕 , 祝各位情人节快乐 。

指针的基本写法是int i = 10 ; int *p = &i ; , 由此我们可以看出 , 指针和变量类似 , 其实 , 指针也是变量 , 我们printf("%#x",p) , 输出的就是i的地址值 , p就是一个变量 , 只是这个变量不普通 , 他可以通过他里面地址 , 操作这个地址里面的内容 , 这就是其强大之处 。那么他在内存中是怎样的呢 ? 下面我们来看看 。

指针操作内存图.png

由图上我们可知 , 指针变量就是用来操作内存空间的 , 当然也可以作为变量存储 , 例如int *p = 100 ; printf("指针变量的值:%d\n",p)这样指针变量p就会输出100 。

既然我们的指针也是变量 , 那么也是可以进行运算的 , 下面我们就来看看 , 指针是怎么样进行运算的 。我们以一个数组输出为例 , 来验证指针变量的运算 , 如下:


void main() {
    
    int arr[] = { 89,20,13,45,68 };

    // 数组地址 , 默认是首个元素的内存地址
    printf("输出数组arr地址:%#x\n", &arr);
    printf("这样也可以获取到数组的地址:%#x\n", arr);
    printf("第一个元素的地址: %#x\n", &arr[0]);

    int* p = &arr;
   // 以普通的方式进行数组输出
    int i = 0;
    for (; i < 5; i++)
    {
        printf("数组元素:%d\n", arr[i]);
    }

    printf("\n");

    // 以指针运算的方式进行数组输出
    int j = 0; 
    for (; j < 5; j++)
    {
        printf("数组元素的值 : %d\n", *p);
        p++;
    }

    printf("\n");

    getchar();
}

从上述代码我们可以看出 , 我们通过变量指针p进行p++操作 , 来获取到数组中的值 , 这样操作的可能是 , 因为数组存储数据的内存空间是连续的 , 可以可以通过同类型的指针 , 进行指针运算来进行内存操作 , 值得注意的是 , 指针类型必须和数组类型一致 ,才能进行内存操作 。由此 , 我们可以得出指针为什么需要类型的答案了:

指针是存储的地址是开始读取的位置 , 类型是读取的长度 , 操作类型必须一致 。

下面我们来做一个实验 , 如果使用不同类型的指针来读取数组 , 这样操作会出现什么情况 , 我们将上述代码的int *p = @arr ;更改为float *p = &arr;会出现什么情况呢 ? 结果如下:

  
数组元素的值 : 0
数组元素的值 : 0
数组元素的值 : 0
数组元素的值 : 0
数组元素的值 : 0

我们使用float类型的指针 , 去操作int类型的数组 , 就完全取不到值了 。为什么会这样呢 ? 我们一探究竟 , 打断点去查看内存的 , 我们输出一下指针变量的值 , 然后对照数组变量的地址,如下:

  
指针变量存储的值:0x101fdac -- 取值:0
数组元素:89 == 数组元素地址:0x101fdac
数组元素:20 == 数组元素地址:0x101fdb0
数组元素:13 == 数组元素地址:0x101fdb4
数组元素:45 == 数组元素地址:0x101fdb8
数组元素:68 == 数组元素地址:0x101fdbc

数组元素的值 : 0 == 指针存储的地址:0x37064000
数组元素的值 : 0 == 指针存储的地址:0x36e40000
数组元素的值 : 0 == 指针存储的地址:0x36da0000
数组元素的值 : 0 == 指针存储的地址:0x36f68000
数组元素的值 : 0 == 指针存储的地址:0x37010000

我们可以看到 , 几乎完全不一致了 , 地址都不相同了 , 我有一个疑惑 , 在第一次打印float指针变量值的时候 , 存储的是数组第一个变量的内存地址 , 但是在循环遍历的时候 , 却不一样了 , 目前不知道是什么原因导致的 , 有知道的希望告知一下 。上述输出完整程序:

以上问题有一个答案了 , 虽然float和int类型都是四字节的 , 但是int 和 float的存储方式不一样 , 所有指针运算会出现不一样 。

  
void main() {
    
    int arr[] = { 89,20,13,45,68 };

    // 数组地址 , 默认是首个元素的内存地址
    printf("输出数组arr地址:%#x\n", &arr);
    printf("这样也可以获取到数组的地址:%#x\n", arr);
    printf("第一个元素的地址: %#x\n", &arr[0]);

    //int* p = &arr;
    float *p = &arr;

    printf("指针变量存储的值:%#x -- 取值:%f\n", p,*p);

    int i = 0;
    for (; i < 5; i++)
    {
        printf("数组元素:%d == 数组元素地址:%#x\n", arr[i],&arr[i]);
    }

    printf("\n");

    int j = 0; 
    for (; j < 5; j++)
    {
        printf("数组元素的值 : %f == 指针存储的地址:%#x\n", *p,p);
        p++;
    }
    
    printf("\n");


    getchar();
}

这次我们分析了指针在内存中的情况 , 以及指针变量的简单运算 , 下次我们来聊聊 , 指针在方法中的运用 , 以及二级指针 。

Android程序员学C系列:
C语言基础及指针①
C语言基础及指针②之指针内存分析
C语言基础及指针③函数与二级指针
C语言基础及指针④函数指针
C语言基础及指针⑤动态内存分配
C语言基础及指针⑥字符操作
C语言基础及指针⑦结构体与指针
C语言基础及指针⑧文件IO
C语言基础及指针⑨联合体与枚举
C语言基础及指针⑩预编译及jni.h分析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,387评论 3 44
  • 1.语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质, 所以我就从“变量”这个东西开始讲起吧...
    金巴多阅读 1,672评论 0 9
  • 一、框架 1、Mac系统及常用工具、进制;C数据类型、常量变量、运算符、表达式、格式化输入输出 2、关系运算符、逻...
    师景福阅读 633评论 0 1
  • 钟爱文字诗话 不恨墨少情多 只愿此爱不去 芬芳常驻心头 2017.6.3.于哈市
    怀古的弄潮儿阅读 240评论 0 3
  • 文|不舍 上午健美操,狠狠出了一身汗,很过瘾。还想尽兴拉伸,活动日渐僵硬的身体。体育也是一门很深的学科,锻炼身体的...
    blue1977阅读 240评论 0 0