屏幕打印

研究问题

  1. Printf,print,println
  2. Sprintf与Sprintf_s
  3. 地址打印%p与%#x区别??

要点:
  • Printf是C语言中格式化输出;print是标准输出,但是不换行;println和print差不多,就是最后会换行:println(“test”)相当于print(“test\n”)。
  • %p指打印地址,没有格式的规定。
  • %x指以十六进制形式打印。
  • \t指后退一个制表符,相当于按了一个Tab键(8个空格键),在第8列打印或输出。
  • int a[10] = {1,2,3,4,5,6,7,8,9,10};
    printf("&a[0]=%p\ta=%p\t&a=%p\n", &a[0],a,&a);

    输出结果:
    输出结果
    第一个\t是从a[0]地址0046FE18中的“4”开始后退一个制表符,第二个\t是从“8”开始后退一个制表符;
    原因:第二个表示a所存储的内存地址,这块内存存在堆上
    第三个表示a本身的内存地址,这块内存在栈上
  • int sprintf_s(char *buffer,size_t sizeOfBuffer,const char *format [,argument] …);
    如:
    sprintf_s(filename,"%s %s %s %s",path1,filepath,path3,path4);

  • %p对地址打印,以大写字母输出,如:0028FEF4
    %#x对地址打印,以小写字母输出,如:0x28fef3

疑难杂症
  1. 为什么内存地址总是以0x00开头?
    在32位系统中,数据总线宽度为32,每次能读取4字节,地址总线宽度为32,因此最大的寻址空间为2^32=4GB,但是最低2位A[0],A[1]是不用于寻址,A[2-31]才能存储器相连,因此只能访问4的倍数地址空间,但是总的寻址空间还是2^30*字长=4GB,因此在内存中所有存放的基本类型数据的首地址的最低两位都是0,除结构体中的成员变量。

  2. 最低2位A[0],A[1]是不用于寻址,是最低2位么?在内存中,一般都是0x00开头,应该是最高两位吧?
    是最低两位, 内存地址没有要求以 0x00 开头, 是你的程序没用到那么多, 或者是你的操作系统设置并没要让程序可以使用全部 4G 空间.
    Unix (like)中(不知道windows是怎么实现的),每个进程都会分配到4G的虚拟内存空间,用于存储进程中的数据(和俗称的虚拟内存不太相同)。然后这4g中的前3g是用户数据(最后1g是系统数据),这3g中从两端向中间分成了各种段地址(如堆,栈,环境变量,BSS,静态常量等),堆和栈正巧处于这两端的末尾,这样设计的原因是为了有足够的空间来加载库文件,和变量的内存,或其他紧急需要分配的内存,以不致造成内存不够,重新找地方分内存,导致内存混乱

  3. 如果是最低2位,倒是是4的倍数,但是实际上有0x00ff4233这样的char变量地址,并不被4整除?
    不被 4 整除的数据, 从可以整除的位置的地址来读, 一次读取 4 个字节, 然后在 CPU 内只使用需要的那个字节. 所以 CPU 对内存的寻址都是可以被 4 整除的, 但是并不要求程序里面的地址都必须被 4 整除.

  4. 因此在内存中所有存放的基本类型数据的首地址的最低两位都是0,是都是0么?应该是地址的最高位吧?
    解析:

    1. 是最低两位, 内存地址没有要求以 0x00 开头, 是你的程序没用到那么多, 或者是你的操作系统设置并没要让程序可以使用全部 4G 空间.
      Unix (like)中(不知道windows是怎么实现的),每个进程都会分配到4G的虚拟内存空间,用于存储进程中的数据(和俗称的虚拟内存不太相同)。然后这4g中的前3g是用户数据(最后1g是系统数据),这3g中从两端向中间分成了各种段地址(如堆,栈,环境变量,BSS,静态常量等),堆和栈正巧处于这两端的末尾,这样设计的原因是为了有足够的空间来加载库文件,和变量的内存,或其他紧急需要分配的内存,以不致造成内存不够,重新找地方分内存,导致内存混乱。
    2. 不被 4 整除的数据, 从可以整除的位置的地址来读, 一次读取 4 个字节, 然后在 CPU 内只使用需要的那个字节. 所以 CPU 对内存的寻址都是可以被 4 整除的, 但是并不要求程序里面的地址都必须被 4 整除.
    3. 地址在内存中的是低位为还是高位和系统的大小端有关. 但是不管如何, 内存中的地址可以是任意值, 并不要求高两位或低两位为 0. 只是 CPU 去寻址内存的时候总是 4 个字节的读, 所以低两位的地址被 CPU 内部处理了.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值