天天看點

計算機系統基礎日志No.1一,原程式二,修改後三,警告原因分析

計算機系統基礎日志No.1

将指令行上的十六進制數字序列轉換為字元串,以"\n"結尾

本日志是關于Linux下gcc編譯運作的16進制轉字元串程式所出現的一系列問題的解釋。

文章目錄

  • 一,原程式
    • 1.源程式
    • 2.虛拟機運作結果及存在的問題
    • 3.程式及其問題分析
      • (1)strtoul函數
      • (2)關于strtoul函數的類型修改
      • (3)stdout函數
      • (4)猜測問題出現的原因
  • 二,修改後
    • 1.源程式
    • 2.修改後第二次編譯
  • 三,警告原因分析

一,原程式

1.源程式

/* Convert sequence of hex digits on command line into a string, terminated by \n */
#include <stdio.h>

int main(int argc, char *argv[]) {
    int i;
    for (i = 1; i < argc; i++) {
	unsigned long dig = strtoul(argv[i], NULL, 16);
	putchar((char) dig);
    }
    putchar('\n');
    return 0;
}
           

2.虛拟機運作結果及存在的問題

/* 輸入參數:30 31 32 33 34 35 36 37 38 39 輸出為:0123456789

[email protected]:~$ gcc hexify.c
hexify.c: In function ‘main’:
hexify.c:6:20: warning: implicit declaration of function ‘strtoul’; did you mean ‘stdout’? [-Wimplicit-function-declaration]
  unsigned long dig=strtoul(argv[i], NULL, 16);
                    ^~~~~~~
                    stdout
[email protected]:~$ gcc hexify.c -o hexify
hexify.c: In function ‘main’:
hexify.c:6:20: warning: implicit declaration of function ‘strtoul’; did you mean ‘stdout’? [-Wimplicit-function-declaration]
  unsigned long dig=strtoul(argv[i], NULL, 16);
                    ^~~~~~~
                    stdout
[email protected]:~$ ./hexify 30 31 32 33 34 35 36 37 38 39
0123456789
           
計算機系統基礎日志No.1一,原程式二,修改後三,警告原因分析

3.程式及其問題分析

(1)strtoul函數

将參數nptr字元串根據參數base來轉換成無符号的長整型數,它是由unsighed long strtoul省略得到。

經過搜尋CSDN其他部落格得知其用法(參考查爾斯.褚)

參數1:字元串起始位址

參數2:傳回字元串有效數字的結束位址,這也是為什麼要用二級指針的原因。

參數3:轉換基數。當base=0,自動判斷字元串的類型,并按10進制輸出,例如"0xa",就會把字元串當做16進制處理,輸出的為10。

計算機系統基礎日志No.1一,原程式二,修改後三,警告原因分析

(2)關于strtoul函數的類型修改

嘗試以unsigned long strtoul,(unsigned long) strtoul,(unsigned) long strtoul等格式補充,發現省略并不改變函數用法

(3)stdout函數

C語言中的 stdout 是一個定義在<stdio.h>的宏(macro),它展開到一個 FILE* (“指向 FILE 的指針”)類型的表達式(不一定是常量),這個表達式指向一個與标準輸出流(standard output stream)相關連的 FILE 對象。

(4)猜測問題出現的原因

猜測丢失了頭檔案 stdlib.h

二,修改後

1.源程式

/* Convert sequence of hex digits on command line into a string, terminated by \n */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
    int i;
    for (i = 1; i < argc; i++) {
	unsigned long dig = strtoul(argv[i], NULL, 16);
	putchar((char) dig);
    }
    putchar('\n');
    return 0;
}
           

2.修改後第二次編譯

/* 輸入參數:30 31 32 33 34 35 36 37 38 39 輸出為:0123456789
[email protected]:~$ gedit hexify.c
[email protected]:~$ gcc hexify.c
[email protected]:~$ gcc hexify.c -o hexify
[email protected]:~$ ./hexify 39 31 32 33 34 35 36 37 38 39
9123456789
           

三,警告原因分析

補充頭檔案 stdlib.h 發現警告消失,而運作結果未改變。經查,該檔案包含了的C語言标準庫函數的定義 。

  stdlib.h裡面定義了五種類型、一些宏和通用工具函數。類型例如size_t、wchar_t、div_t、ldiv_t和lldiv_t;宏例如EXIT_FAILURE、EXIT_SUCCESS、RAND_MAX和MB_CUR_MAX等等;常用的函數如malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、 srand()、exit()等等。