本人的C開源庫——基於GNU11標準

來源:互聯網
上載者:User

1、將位元組數組轉為整型(小端)

介面為:

#define zenny_chenBYTES2INTEGER(buffer, length, type)

buffer:const unsigned char*類型,指向位元組數組的起始地址

length:size_t類型,指示要轉為整型的數組位元組長度

type:四種類型,

zenny_chenBYTES2INTEGER_TYPE_SIGNED32表示32位帶符號整型,最後返回int;

zenny_chenBYTES2INTEGER_TYPE_UNSIGNED32表示無符號32位整型,最後返回unsigned int;

zenny_chenBYTES2INTEGER_TYPE_SIGNED64表示帶符號64位整型,最後返回long long int;

zenny_chenBYTES2INTEGER_TYPE_UNSIGNED64表示無符號64位整型,最後返回unsigned long long int

 

代碼如下:

函數實現:

int ZennyChenBytes2SInteger(const unsigned char *pBuff, size_t length){    int value = 0;    int shift = 0;    for(size_t i = 0; i < length; i++)    {        int tmp = pBuff[i];        value += tmp << shift;        shift += 8;    }    return value;}unsigned ZennyChenBytes2UInteger(const unsigned char *pBuff, size_t length){    unsigned value = 0;    int shift = 0;    for(size_t i = 0; i < length; i++)    {        unsigned tmp = pBuff[i];        value += tmp << shift;        shift += 8;    }    return value;}long long ZennyChenBytes2SLong(const unsigned char *pBuff, size_t length){    long long value = 0;    int shift = 0;    for(size_t i = 0; i < length; i++)    {        long long tmp = pBuff[i];        value += tmp << shift;        shift += 8;    }    return value;}unsigned long long ZennyChenBytes2ULong(const unsigned char *pBuff, size_t length){    unsigned long long value = 0;    int shift = 0;    for(size_t i = 0; i < length; i++)    {        unsigned long long tmp = pBuff[i];        value += tmp << shift;        shift += 8;    }    return value;}

以下是介面以及測試案例

#define zenny_chenBYTES2INTEGER_TYPE_SIGNED32       int#define zenny_chenBYTES2INTEGER_TYPE_UNSIGNED32     unsigned int#define zenny_chenBYTES2INTEGER_TYPE_SIGNED64       long long int#define zenny_chenBYTES2INTEGER_TYPE_UNSIGNED64     unsigned long long int#define zenny_chenBYTES2INTEGER(buffer, length, type)   _Generic((type)0, zenny_chenBYTES2INTEGER_TYPE_SIGNED32:ZennyChenBytes2SInteger, zenny_chenBYTES2INTEGER_TYPE_UNSIGNED32:ZennyChenBytes2UInteger, zenny_chenBYTES2INTEGER_TYPE_SIGNED64:ZennyChenBytes2SLong, zenny_chenBYTES2INTEGER_TYPE_UNSIGNED64:ZennyChenBytes2ULong, default:ZennyChenBytes2SLong)((buffer), (length))int main(int argc, const char * argv[]){    @autoreleasepool     {                // insert code here...        // int        int si = -1;        NSData *data = [NSData dataWithBytes:&si length:sizeof(si)];        unsigned char *buff = (unsigned char*)malloc([data length]);        [data getBytes:buff length:[data length]];        NSLog(@"The value is: %d", zenny_chenBYTES2INTEGER(buff, [data length], zenny_chenBYTES2INTEGER_TYPE_SIGNED32));        free(buff);                // unsigned        unsigned ui = -1;        data = [NSData dataWithBytes:&ui length:sizeof(ui)];        buff = (unsigned char*)malloc([data length]);        [data getBytes:buff length:[data length]];        NSLog(@"The value is: %u", zenny_chenBYTES2INTEGER(buff, [data length], zenny_chenBYTES2INTEGER_TYPE_UNSIGNED32));        free(buff);                // long long        unsigned sll = 0x8888888888LL;        data = [NSData dataWithBytes:&sll length:sizeof(sll)];        buff = (unsigned char*)malloc([data length]);        [data getBytes:buff length:[data length]];        NSLog(@"The value is: 0x%.16llX", zenny_chenBYTES2INTEGER(buff, [data length], zenny_chenBYTES2INTEGER_TYPE_SIGNED64));        free(buff);                // unsigned long long        unsigned ull = 0x8888888888LL;        data = [NSData dataWithBytes:&ull length:sizeof(ull)];        buff = (unsigned char*)malloc([data length]);        [data getBytes:buff length:[data length]];        NSLog(@"The value is: 0x%.16llX", zenny_chenBYTES2INTEGER(buff, [data length], zenny_chenBYTES2INTEGER_TYPE_SIGNED64));        free(buff);    }        return 0;}

 
2、使用棧切換來適應高深度的遞迴函式調用

由於在很多情況下,使用遞迴形式使得演算法既簡潔,又優美,甚至執行速度更快。比如二叉樹搜尋這種演算法,顯然使用遞迴形式比非遞迴要簡潔很多,而且事實上執行效率並不比非遞迴形式要差。由於這個過程中,即便用非遞迴形式仍然需要將節點壓入棧中,而且這個棧操作完全是通過軟體執行的。而天然的棧實際上就針對棧指標寄存器進行操作,從而使得其執行效率比自己做的棧資料結構來得高效。

然而一般使用者棧的大小就幾十KB,如果調用深度較深,所需的棧大小超出使用者棧的最大大小,則會引發運行時異常。這個時候,我們可以通過自己分配一Block Storage空間,然後將當前棧空間切換到我們所分配的儲存空間來解決這個問題。下面的範例程式碼是棧空間切換的一個比較基本的例子:

/* * zasm.asm * *  Created on: 2013-1-13 *      Author: Zenny Chen */.text.align 2.globl _Zenny_switch_stack, _Zenny_restore_stack// const void* Zenny_switch_stack(const void *pMem, size_t length);_Zenny_switch_stack:    lea     4(%esp), %eax    lea     (%ecx, %edx, 1), %ecx    mov     (%esp), %edx    mov     %ecx, %esp    push    %edx    ret// void Zenny_restore_stack(const void *pOrgStack);_Zenny_restore_stack:    mov     (%esp), %eax    mov     %ecx, %esp    push    %eax    ret

下面是源檔案:

/* ============================================================================ Name        : recursionTest.c Author      : Zenny Chen Version     : Copyright   : Your copyright notice Description : Hello World in C, Ansi-style ============================================================================ */#include <stdio.h>#include <stdlib.h>extern const void* __fastcall Zenny_switch_stack(const void *pMem, size_t length);extern void __fastcall Zenny_restore_stack(const void *pOrgStack);static int RecursionSum(int n){    if(n == 0)        return 0;    else        return n + RecursionSum(n - 1);}static int IterationSum(int n){    int sum = 0;    for(int i = 0; i <= n; i++)        sum += i;    return sum;}static void DoRecursionTest(int *pResult){    int sum = RecursionSum(100000);    *pResult = sum;}static void stack_swtich_test(void){    /** Outside the switch-stack region **/    void *pMem = malloc(4 * 1024 * 1024);    int result;    register int* const pResult = &result;    const void *pOrgStack = Zenny_switch_stack(pMem, 4 * 1024 * 1024);    /** Inside the switch-stack region **/    DoRecursionTest(pResult);    Zenny_restore_stack(pOrgStack);    /** Outside the switch-stack region **/    printf("The result is: %d\n", result);    free(pMem);}int main(void){    puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */    stack_swtich_test();    printf("The sum result is: %d\n", IterationSum(100000));    return EXIT_SUCCESS;}

 

上述代碼的編譯運行環境為:Lenovo Z475 AMD APU A6-3420M,4GB DDR3,MinGW GCC 4.6.2。

這裡要注意的是,為了防止編譯器有時對esp寄存器的混合使用,這裡推薦在使用自己開闢的儲存空間作為棧空間時,使用一個或一系列的函數調用,並且函數的參數盡量少。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.