C 如何將輸出的地址轉化為十進制數


 

•需求

  這兩天在看內存對齊的相關問題,因此產生了一個,如何將地址轉換為十進制數?

  對於如下程序:

void func()
{
    int a = 10;

    printf("a 的地址為:%p\n", &a);
}

  通過格式控制符  %p 以及取地址符  &a ,可以很方便的輸出變量 a 的地址。

   printf 函數中對於  %p  一般以十六進制的方式輸出指針的值:

  一般而言,十六進制對於分析各個變量間的內存空間位置沒那么方便,此時往往需要將其轉化為十進制。

  如何那么,該轉換呢?

•十六進制地址轉十進制

方法一

  復制輸出控制台輸出的十六進制代碼,通過在線進制轉換工具將其轉化為十進制。

  是不是簡單粗暴,但是當要轉化的地址多的時候,這個方法往往比較繁瑣,那么還有沒有其他方法呢?

方法二

  首先,編寫一個十六進制轉十進制的代碼,下面做一下簡單介紹。

  • 十進制:逢十進一,數字中含有 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 :

$\begin{aligned} 0XFA07B &= F\times 16^{4}+ A\times 16^{3} + 0\times 16^{2} + 7\times 16^{1} + B\times 16^{0} \\ &= 15\times 16^{4}+ 10\times 16^{3} + 0\times 16^{2} + 7\times 16^{1} + 11\times 16^{0} \\ &= 1024123\end{aligned} $

  是不是超級簡單,那我們通過編程語言來實現一下:

int change(char c)//分解出每一位對應的數字
{
    if (c >= 'a' && c <= 'f')
        return c - 'a' + 10;
    if (c >= 'A' && c <= 'F')
        return c - 'A' + 10;
    if (c >= '0' && c <= '9')
        return c - '0';
 
    return 0;//如果是前綴的X,輸出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[i]);
        ans += num * x;
        x *= 16;
    }
    return ans;
}

  這兒有一道進制轉換的題目,有興趣的小伙伴可以用來測試一下程序的正確性:華為機試|HJ5 進制轉換

  有了十六進制轉十進制的方法,那么,如何將地址輸出的十六進制代碼轉化為字符串呢?

  這樣操作?

void func()
{
    int a = 10;
    string str = & a;
}

  顯然不行,編譯都不通過;

  這可如何是好?

  莫慌,我們可以曲線轉換,下面介紹一下 freopen函數用法。

freopen

函數簡介

  freopen 是被包含於 C標准庫頭文件  stdio.h  中的一個函數,用於重定向輸入輸出流。

  該函數可以在不改變代碼原貌的情況下改變輸入輸出環境,但使用時應當保證流是可靠的。

函數原型

 *FILE freopen( const char *_Filename, const char *_Mode, FILE _Stream ); 

  具體內容,請參考:🔗

  接下來,通過 freopen 實現來完美的實現地址轉十進制。

CODE

#pragma warning(disable:4996)//取消返回值被忽略的報錯
#pragma warning(disable:4786)//取消使用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;
    if (c >= '0' && c <= '9')
        return c - '0';
 
    return 0;//如果是前綴的X,輸出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[i]);
        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;
}

  我們設置的 freopen 的第一個參數就只是一個文件名,那么該文件默認放到項目所在地址,VS可通過右擊找到該項目所在文件夾。

  打開  addressToDecimal.txt 你會發現里面的內容就是包含兩項:

  1. 通過 printf 輸出的 a 的地址
  2. 通過 cout 輸出的信息

  完結撒花~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM