printf函数的细节问题探索
来源:互联网 发布:淘宝买口服催情药 编辑:程序博客网 时间:2024/06/14 07:08
在C语言的学习中,最先学习的,也是大家最熟悉的肯定就是printf函数了,今天来给大家来说一下printf函数的一些细节问题。
代码:
char arr[2][3] = {'a','b','c','d','e','f'};<span style="color:#FF0000;">int *p = arr;</span>int i;for(i=0;i<6;i++){printf("%x\t%c\t%p\n",*(p+i),*(p+i),p+i);}
大家想一下,一个指向整型数据的一维指针,可以来存放字符型二维数组的地址吗?
编译过后我们发现,只是出现了一个警告
警告:从不兼容的指针类型初始化怎么来消除这个警告呢?只需要改动一点点就行了int *p = (int *)arr
这个只是一个小问题,接下来我们就要来打印出来了哦,大家想一下,我们打印出来的第一行应该是怎样的数据呢?
我们来单独打印出来看看,会出现什么结果呢?
printf("%c",*(p+0));这个会出现什么结果呢?乱码?还是a?还是直接打出来abcd?或者dcba?
一切以结果为准,编译执行过后,我们发现
结果:a
按照这个想法,那么我们再用整型输出看看
printf("%d\n",*(p+0));我们当然会想当然地会输出97,因为字符输出是a嘛
但是,大家会发现,出错了,结果是1684234849,对吧。大家想一下是为什么会出现这种问题呢?
----------分隔线--------------------------------
最后揭谜底了
我们在强制类型转换的时候,原来我们把殖民地arr[0]相近的几个元素一起来“合成”了一个整型数据,这是什么意思呢?
由于p是一个指向整型数据的指针,所以*(p+0)占4个字节,那么我们printf("%d",*(p+0));是哪4个字节的数据呢?原来就是把我们的arr[0],arr[1],arr[2],arr[3]当成了一个整型数据输出来,那么为什么我们用printf("%c",*(p+0));能打印出来a呢?这,就要说到我们的另外一个问题了
当我们使用printf的时候,我们关心得最多的就是引号后面的东西,其实引号里面也是有讲究的,当我们用"%d",输出的时候,我们就按照十进制输出到屏幕,而如果我们用"%c"时呢,就会按照字符型输出到屏幕。
但是,当我们用"%c"输出时,这是我们只能向屏幕输出1个字节的数据,如果我们的输出参数是一个4个字节的整型数据,那么我们就会只取低8位的数据来输出,所以我们用整型数据输出的时候会出现一个我们不认识的乱码,而我们用字符型输出能输出我们想看到的a。
最后再说一句,其实1684234849这个数字也不是什么乱码,如果我们化成十六进制我们就会发现其实它是0x64636261,0x61其实就是a的ascii码。
再来多说一个关于数据整合的问题,在我们的对底层的操作的时候,经常会遇到数据的整合,那么这个原理是什么样的呢?其实这是很简单的一个问题,我们来慢慢说。
我们来举一个例子,
十进制数:15
十六进制数:0x0e
二进制数:0000 1111
有些人可能学会了十六进制转化二进制过后,会把十进制转化二进制搞混淆,会认为就是把5的二进制和1的二进制组合起来就是了,即:0001 0101,这显然是不对的。来举一个实例吧!
char carr[2] = {'a','b'};short *p = carr;printf("%d\n",*p);pirntf("%x\n",*p);大家看,这个简单的程序,我们把carr的地址存放在一个指向短整型的指针里面, 我们来看看结果
251856261这个是结果为什么会出现这种情况前面已经说了,现在我们来看看这个存储的原理
我们的程序存储carr 时是存的'a'和'b'的ascii码,十进制就是97和98,而我们存储'a'和'b'时是连续存储的,所以我们还要转化成二进制来进行计算,97的二进制是0110 0001,98的二进制是0110 0010,再来整合,记住计算机的大端小端,我们的电脑的98在前,97在后,即为:0110 0010 0110 0001,这个二进制数计算下来就是我们的25185,这就是计算机来处理数据时的过程,而我们的十六进制就简单了,我们知道,每4个二进制数就能合成一个十六进制数,所以自然就是0x6261了。
- printf函数的细节问题探索
- scanf,printf函数细节
- printf函数栈的问题
- Printf 的格式输出探索
- printf函数的求值顺序问题
- printf函数的参数压栈问题
- printf函数本身的参数问题
- 关于printf函数的返回值问题
- printf()函数的行缓冲问题
- printf函数参数问题
- printf 函数问题
- printf函数缓冲区问题
- printf函数缓冲区问题
- 【源译】web_url函数的一个细节问题
- web_url函数的一个细节问题【转】
- 字符串操作函数的一些细节问题
- 和函数问题的细节思考
- main函数细节问题
- Android 学习之CalendarManager日历管理工具类
- 一致性Hash
- discuz当qq绑定超过5个网址时 如何解除绑定qq
- grails 事务 Transactional
- linux命令行计算器
- printf函数的细节问题探索
- Android增量更新
- Struts 2 – Resource bundle example
- SecureCRT 自动设置环境变量(自动设置编码)
- Python的安装和使用
- hdu-1004 Let the Balloon Rise
- 禁止横屏设置
- startx失败后,dbus的处理
- spark core源码分析16 Shuffle详解-读流程