日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言补丁原理,C语言可变长參数实现原理

發布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言补丁原理,C语言可变长參数实现原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

(1)????? C語言可變參數

我們能夠從C語言的printf得出可變參數的作用。printf函數的原型例如以下:

int printf ( const char * format, ... );

通過使用可變個數參數,就是傳入的參數個數是可變的,如printf須要依據format實參傳入多個實參。

(2)????? C語言可變參數的使用

以下一個函數myprintf是自己實現的比較簡單的printf函數。不完整可是能夠說明可變參數的使用方法。

/*

* Author: guojun07

*/

#include

#include

#include

#include

void myprintf(char *format, ...) {

va_list ap;

int pos = 0;

int int_val = 0;

float f_val;

char buf[64];

memset(buf, 0, 64);

// 得到全部的參數放到下一個list中ap中

va_start(ap, format);

while (format[pos] != ' ') {

// 推斷'%'。表示要得到下一個參數

if (format[pos] == '%') {

pos ++;

switch(format[pos]) {

case 'd':

case 'u':

// 得到ap中的下一個參數

int_val = va_arg(ap, int);

sprintf(buf, "%d", int_val);

// 將數據寫到標準輸出

write(STDOUT_FILENO, buf, strlen(buf));

memset(buf, 0, 64);

pos ++;

break;

case 'f':

// 得到ap中的下一個參數

f_val = (float)va_arg(ap, double);

sprintf(buf, "%f", f_val);

// 將數據寫到標準輸出

write(STDOUT_FILENO, buf, strlen(buf));

memset(buf, 0, 64);

pos ++;

break;

default:

break;

}

} else {

write(STDOUT_FILENO, &(format[pos]), 1);

pos ++;

}

}

}

int main(void){

myprintf("this is a testing, i = %d, u = %u, f = %f

", -1, 5, 0.2);

return 0;

}

程序的數據結果例如以下:

guojun8@guojun8-desktop:~/test/valist$ ./main

this is a testing, i = -1, u = 5, f = 0.200000

(3)????? 實現

以下介紹C語言可變長度參數的實現。事實上現與一個數據結構(va_list)和三個宏(va_start, va_end, va_arg)相關,從源代碼中能夠看到這些實現以下的來自linux內核源代碼中的文件(include/acpi/platform/acenv.h)

#ifndef _VALIST

#define _VALIST

typedef char *va_list;

#endif??????? /* _VALIST */

/*

* Storage alignment properties

*/

#define? _AUPBND??????????????? (sizeof (acpi_native_int) - 1)

#define? _ADNBND??????????????? (sizeof (acpi_native_int) - 1)

/*

* Variable argument list macro definitions

*/

#define _bnd(X, bnd)??????????? (((sizeof (X)) + (bnd)) & (~(bnd)))

#define va_arg(ap, T)?????????? (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))

#define va_end(ap)????????????? (void) 0

#define va_start(ap, A)???????? (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))

a)???????? va_list

從實現中能夠看出va_list類型實際上就是一個指針。

b)??????? va_start

這個宏的作用是將T所指向的參數后面的內容放到ap中。當中_bnd (A,_AUPBND)是返回A的size并與系統的機器位數對齊。由于參數在棧中的地址一定是與系統的字長對齊的,當中acpi_native_int就表示機器字長。

c)???????? va_end

這個宏的作用就是返回0。

d)??????? va_arg

這個宏的作用是取得ap指向的當前的參數,并將ap指向參數列表中的下一個參數。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的C语言补丁原理,C语言可变长參数实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。