php中文网 | cnphp.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 711|回复: 0

C 如何将输出的地址转化为十进制数

[复制链接]

3142

主题

3152

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

UID
1
威望
0
积分
7956
贡献
0
注册时间
2021-4-14
最后登录
2024-11-22
在线时间
763 小时
QQ
发表于 2022-3-23 16:37:31 | 显示全部楼层 |阅读模式
需求
  这两天在看内存对齐的相关问题,因此产生了一个,如何将地址转换为十进制数?

  对于如下程序:
[mw_shl_code=applescript,true]void func()
{
    int a = 10;

    printf("a 的地址为:%p\n", &a);
}[/mw_shl_code]
通过格式控制符  %p 以及取地址符  &a ,可以很方便的输出变量 a 的地址。

   printf 函数中对于  %p  一般以十六进制的方式输出指针的值:
image.png
 一般而言,十六进制对于分析各个变量间的内存空间位置没那么方便,此时往往需要将其转化为十进制。

  如何那么,该转换呢?
十六进制地址转十进制
方法一
  复制输出控制台输出的十六进制代码,通过在线进制转换工具将其转化为十进制。

  是不是简单粗暴,但是当要转化的地址多的时候,这个方法往往比较繁琐,那么还有没有其他方法呢?

方法二
  首先,编写一个十六进制转十进制的代码,下面做一下简单介绍。

十进制:逢十进一,数字中含有 0,1,2,3,4,5,6,7,8,9
十六进制:逢十六进一,表示形式比较特殊,0~9 正常用数字表示,10~15 用英文字母 A~F(或 a~f) 来表示
10 用 A 表示
11 用 B 表示
12 用 C 表示
13 用 D 表示
14 用 E 表示
15 用 F 表示
  在十六进制的表示中,大写字母小写字母都可以,一般有个 0x 前缀表示当前的数用十六进制表示。

  有了相关的知识储备,我们来看看十六进制如何转化为十进制,假设需要转换的十六进制数为 0XFA7B :

image.png
  是不是超级简单,那我们通过编程语言来实现一下:
[mw_shl_code=applescript,true]int change(char c)//分解出每一位对应的数字
{
    if (c >= 'a' && c <= 'f')
        return c - 'a' + 10;
    if (c >= 'A' && c <= 'F')
        return c - 'A' + 10;
    return c - '0';
}
int hexToDecimal(const string& str)//十六进制转十进制,十六进制保存在字符串中
{
    int len = str.length();
    int x = 1;
    int ans = 0;
    for (int i = len - 1; i >= 0; i--)//从右往左依次处理每一位
    {
        int num = change(str);
        ans += num * x;
        x *= 16;
    }
    return ans;
}[/mw_shl_code]
有了十六进制转十进制的方法,那么,如何将地址输出的十六进制代码转化为字符串呢?

  这样操作?
[mw_shl_code=applescript,true]void func()
{
    int a = 10;
    string str = & a;
}[/mw_shl_code]
显然不行,编译都不通过;
image.png
这可如何是好?

  莫慌,我们可以曲线转换,下面介绍一下 freopen函数用法。

freopen
函数简介

  freopen 是被包含于 C标准库头文件  stdio.h  中的一个函数,用于重定向输入输出流。

  该函数可以在不改变代码原貌的情况下改变输入输出环境,但使用时应当保证流是可靠的。

函数原型

*FILE freopen( const char filename, const char mode, FILE stream );

参数介绍

filename:需要重定向到的文件名或文件路径
mode:代表文件访问权限的字符串
"r":表示 只读访问
"w":表示 只写访问
"a":表示 追加写入
stream:需要被重定向的文件流
stdin 表示从文件中读取
stdout 表示输出到文件中
  接下来,通过 freopen 实现来完美的实现地址转十进制。
[mw_shl_code=applescript,true]#pragma warning(disable:4996)//VS2022取消返回值被忽略的报错
#pragma warning(disable:4786)//VS2022取消使用STL中一些容器的报错
#include<bits/stdc++.h>
using namespace std;


int change(char c)//分解出每一位对应的数字
{
    if (c >= 'a' && c <= 'f')
        return c - 'a' + 10;
    if (c >= 'A' && c <= 'F')
        return c - 'A' + 10;
    return c - '0';
}
int hexToDecimal(const string& str)//十六进制转十进制,十六进制保存在字符串中
{
    int len = str.length();
    int x = 1;
    int ans = 0;
    for (int i = len - 1; i >= 0; i--)//从右往左依次处理每一位
    {
        int num = change(str);
        ans += num * x;
        x *= 16;
    }
    return ans;
}
void func()
{
    int a = 10;
    printf("%p\n", &a);//通过输出重定向,将地址输出到addressToDecimal.txt中
    string str;
    cin >> str;//从addressToDecimal.txt读取已保存的a的地址
    cout << "a的地址为:" << str << ",十进制为:" << hexToDecimal(str) << endl;
}
int main()
{
    freopen("addressToDecimal.txt", "r", stdin);
    freopen("addressToDecimal.txt", "w", stdout);

    func();
    return 0;
}[/mw_shl_code]
我们设置的 freopen 的第一个参数就只是一个文件名,那么该文件默认放到项目所在地址,VS可通过右击找到该项目所在文件夹。 image.png
打开  addressToDecimal.txt 你会发现里面的内容就是包含两项:

通过 printf 输出的 a 的地址
通过 cout 输出的信息
image.png





上一篇:Oneops运维系统
下一篇:swing 实现用户登录注册界面(不使用数据库) 实现的功能
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|php中文网 | cnphp.com ( 赣ICP备2021002321号-2 )

GMT+8, 2024-11-22 09:36 , Processed in 0.296835 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

申明:本站所有资源皆搜集自网络,相关版权归版权持有人所有,如有侵权,请电邮(fiorkn@foxmail.com)告之,本站会尽快删除。

快速回复 返回顶部 返回列表