stdargc語言
① 在c語言里標准函數存放在什麼文件中
C語言標准庫函數存放在頭文件當中,使用相應函數時需要用include引用先關頭文件。
C語言程序設計里,C 標准函數(C Standard library)是所有目前符合標準的頭文件(head
file)的集合,以及常用的函數庫實現程序,例如 I/O輸入輸出和字串符控制。不像 COBOL、Forrian和 PL/I等編程語言,在 C
語言的工作任務里不會包含嵌入的關鍵字,所以幾乎所有的 C 語言程序都是由標准函數庫的函數來創建的。下面列出C89及C99中C語言標准函數庫的頭文件。
C89中標準的頭文件
<assert.h> 設定斷言點
<ctype.h> 字元處理
<errno.h> 錯誤報告
<float.h> 定義與實現相關的浮點值勤
<limits.h> 定義與實現相關的各種極限值
<locale.h> 支持函數setlocale()
<math.h> 數學函數庫使用的各種定義
<setjmp.h> 支持非局部跳轉
<signal.h> 定義信號值
<stdarg.h> 支持可變長度的變元列表
<stddef.h> 定義常用常數
<stdio.h> 支持文件輸入和輸出
<stdlib.h> 其他各種聲明
<string.h> 支持串函數
<time.h> 支持系統時間函數
C99新增的頭文件和庫
<complex.h> 支持復數演算法
<fenv.h> 給出對浮點狀態標記和浮點環境的其他方面的訪問
<inttypes.h> 定義標準的、可移植的整型類型集合。也支持處理最大寬度整數的函數
<iso646.h> 首先在此1995年第一次修訂時引進,用於定義對應各種運算符的宏
<stdbool.h> 支持布爾數據類型類型。定義宏bool,以便兼容於C++
<stdint.h> 定義標準的、可移植的整型類型集合。該文件包含在<inttypes.h>中
<tgmath.h> 定義一般類型的浮點宏
<wchar.h> 首先在1995年第一次修訂時引進,用於支持多位元組和寬位元組函數
<wctype.h> 首先在1995年第一次修訂時引進,用於支持多位元組和寬位元組分類函數
② #include <stdarg.h>這個頭文件是什麼意思
stdarg.h是C語言中C標准函式庫的標頭檔,stdarg是由standard(標准) arguments(參數)簡化而來,主要目的為讓函式能夠接收不定量參數
③ stdarg.h的介紹
stdarg.h是C語言中C標准函數庫的頭文件,stdarg是由standard(標准) arguments(參數)簡化而來,主要目的為讓函數能夠接收可變參數。C++的cstdarg頭文件中也提供這樣的功能;雖然與C的頭文件是兼容的,但是也有沖突存在。可變參數函數(Variadic functions)是stdarg.h內容典型的應用,雖然也可以使用在其他由可變參數函數調用的函數(例如,vprintf)。
④ C語言頭文件有哪些
字元處理函數
本類別函數用於對單個字元進行處理,包括字元的類別測試和字元的大小寫轉換
頭文件 ctype.h
函數列表<>
函數類別 函數用途 詳細說明
字元測試 是否字母和數字 isalnum
是否字母 isalpha
是否控制字元 iscntrl
是否數字 isdigit
是否可顯示字元(除空格外) isgraph
是否可顯示字元(包括空格) isprint
是否既不是空格,又不是字母和數字的可顯示字元 ispunct
是否空格 isspace
是否大寫字母 isupper
是否16進制數字(0-9,A-F)字元 isxdigit
字元大小寫轉換函數 轉換為大寫字母 toupper
轉換為小寫字母 tolower
地區化
本類別的函數用於處理不同國家的語言差異。
頭文件 local.h
函數列表
函數類別 函數用途 詳細說明
地區控制 地區設置 setlocale
數字格式約定查詢 國家的貨幣、日期、時間等的格式轉換 localeconv
數學函數
本分類給出了各種數學計算函數,必須提醒的是ANSI C標准中的數據格式並不符合IEEE754標准,一些C語言編譯器卻遵循IEEE754(例如frinklin C51)
頭文件 math.h
函數列表
函數類別 函數用途 詳細說明
錯誤條件處理 定義域錯誤(函數的輸入參數值不在規定的范圍內)
值域錯誤(函數的返回值不在規定的范圍內)
三角函數 反餘弦 acos
反正弦 asin
反正切 atan
反正切2 atan2
餘弦 cos
正弦 sin
正切 tan
雙曲函數 雙曲餘弦 cosh
雙曲正弦 sinh
雙曲正切 tanh
指數和對數 指數函數 exp
指數分解函數 frexp
乘積指數函數 fdexp
自然對數 log
以10為底的對數 log10
浮點數分解函數 modf
冪函數 冪函數 pow
平方根函數 sqrt
整數截斷,絕對值和求余數函數 求下限接近整數 ceil
絕對值 fabs
求上限接近整數 floor
求余數 fmod
本分類函數用於實現在不同底函數之間直接跳轉代碼。 頭文件 setjmp.h io.h
函數列表
函數類別 函數用途 詳細說明
保存調用環境 setjmp
恢復調用環境 longjmp
信號處理
該分類函數用於處理那些在程序執行過程中發生例外的情況。
頭文件 signal.h
函數列表
函數類別 函數用途 詳細說明
指定信號處理函數 signal
發送信號 raise
可變參數處理
本類函數用於實現諸如printf,scanf等參數數量可變底函數。
頭文件 stdarg.h
函數列表
函數類別 函數用途 詳細說明
可變參數訪問宏 可變參數開始宏 va_start
可變參數結束宏 va_end
可變參數訪問宏 訪問下一個可變參數宏 va_arg
輸入輸出函數
該分類用於處理包括文件、控制台等各種輸入輸出設備,各種函數以「流」的方式實現
頭文件 stdio.h
函數列表
函數類別 函數用途 詳細說明
文件操作
刪除文件 remove
修改文件名稱 rename
生成臨時文件名稱 tmpfile
得到臨時文件路徑 tmpnam
文件訪問 關閉文件 fclose
刷新緩沖區 fflush
打開文件 fopen
將已存在的流指針和新文件連接 freopen
設置磁碟緩沖區 setbuf
設置磁碟緩沖區 setvbuf
格式化輸入與輸出函數 格式輸出 fprintf
格式輸入 fscanf
格式輸出(控制台) printf
格式輸入(控制台) scanf
格式輸出到緩沖區 sprintf
從緩沖區中按格式輸入 sscanf
格式化輸出 vfprintf
格式化輸出 vprintf
格式化輸出 vsprintf
字元輸入輸出函數 輸入一個字元 fgetc
字元串輸入 fgets
字元輸出 fputc
字元串輸出 fputs
字元輸入(控制台) getc
字元輸入(控制台) getchar
字元串輸入(控制台) gets
字元輸出(控制台) putc
字元輸出(控制台) putchar
字元串輸出(控制台) puts
字元輸出到流的頭部 ungetc
直接輸入輸出 直接流讀操作 fread
直接流寫操作 fwrite
文件定位函數 得到文件位置 fgetpos
文件位置移動 fseek
文件位置設置 fsetpos
得到文件位置 ftell
文件位置復零位 remind
錯誤處理函數 錯誤清除 clearerr
文件結尾判斷 feof
文件錯誤檢測 ferror
得到錯誤提示字元串 perror
實用工具函數
本分類給出了一些函數無法按以上分類,但又是編程所必須要的。
頭文件 stdlib.h
函數列表
函數類別 函數用途 詳細說明
字元串轉換函數 字元串轉換為整數 atoi
字元串轉換為長整數 atol
字元串轉換為浮點數 strtod
字元串轉換為長整數 strtol
字元串轉換為無符號長整型 strtoul
偽隨機序列產生函數 產生隨機數 rand
設置隨機函數的起動數值 srand
存儲管理函數 分配存儲器 calloc
釋放存儲器 free
存儲器分配 malloc
重新分配存儲器 realloc
環境通信 中止程序 abort
退出程序執行,並清除環境變數 atexit
退出程序執行 exit
讀取環境參數 getenv
程序掛起,臨時執行一個其他程序 system
搜索和排序工具 二分查找(數據必須已排序) bsearch
快速排序 qsort
整數運算函數 求絕對值 abs
div
得到除法運算底商和余數
求長整形底絕對值 labs
求長整形除法的商和余數 ldiv
多位元組字元函數 得到多位元組字元的位元組數 mblen
得到多位元組字元的位元組數 mbtowc
多位元組字元轉換 wctomb
多位元組字元的字元串操作 將多位元組串轉換為整數數組 mbstowcs
將多位元組串轉換為字元數組 mcstowbs
字元串處理
本分類的函數用於對字元串進行合並、比較等操作
頭文件 string.h
函數列表
函數類別 函數用途 詳細說明
字元串拷貝 塊拷貝(目的和源存儲區不可重疊) memcpy
塊拷貝(目的和源存儲區可重疊) memmove
串拷貝 strcpy
按長度的串拷貝 strncpy
字元串連接函數 串連接 strcat
按長度連接字元串 strncat
串比較函數 塊比較 memcmp
字元串比較 strcmp
字元串比較(用於非英文字元) strcoll
按長度對字元串比較 strncmp
字元串轉換 strxfrm
字元與字元串查找 字元查找 memchr
字元查找 strchr
字元串查找 strcspn
字元串查找 strpbrk
字元串查找 strspn
字元串查找 strstr
字元串分解 strtok
雜類函數 字元串設置 memset
錯誤字元串映射 strerror
求字元串長度 strlen
日期和時間函數
本類別給出時間和日期處理函數
頭文件 time.h
函數列表
函數類別 函數用途 詳細說明
時間操作函數 得到處理器時間 clock
得到時間差 difftime
設置時間 mktime
得到時間 time
時間轉換函數 得到以ASCII碼表示的時間 asctime
得到字元串表示的時間 ctime
得到指定格式的時間 strftime
函數庫未來的發展方向
本部分用於說明各類別函數庫在將來如何發展。
序號 庫類別 頭文件 詳細說明
1 錯誤處理 errno.h
2 字元處理 ctype.h
3 地區化 local.h
4 數學函數 math.h
5 信號處理 signal.h
6 輸入輸出 stdio.h
7 實用工具程序 stdlib.h
8 字元串處理 string.h
⑤ c語言中的void printlog(char *format,...)這是什麼意思
是可變參數,是c的一個語法現象,我在電腦上保存的一些資料,希望對你有用。
一、什麼是可變參數
我們在C語言編程中有時會遇到一些參數個數可變的函數,例如printf()函數,其函數原型為:
int printf( const char* format, ...);
它除了有一個參數format固定以外,後面跟的參數的個數和類型是可變的(用三個點"…"做參數佔位符),實際調用時可以有以下的形式:
printf("%d",i);
printf("%s",s);
printf("the number is %d ,string is:%s", i, s);
以上這些東西已為大家所熟悉。但是究竟如何寫可變參數的C函數以及這些可變參數的函數編譯器是如何實現,這個問題卻一直困擾了我好久。本文就這個問題進行一些探討,希望能對大家有些幫助.
二、可變參數在編譯器中的處理
我們知道va_start,va_arg,va_end是在stdarg.h中被定義成宏的, 由於1)硬體平台的不同 2)編譯器的不同,所以定義的宏也有所不同,下面看一下VC++6.0中stdarg.h里的代碼(文件的路徑為VC安裝目錄下的\vc98\include\stdarg.h)
typedef char * va_list;
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
下面我們解釋這些代碼的含義:
1、首先把va_list被定義成char*,這是因為在我們目前所用的PC機上,字元指針類型可以用來存儲內存單元地址。而在有的機器上va_list是被定義成void*的
2、定義_INTSIZEOF(n)主要是為了某些需要內存的對齊的系統.這個宏的目的是為了得到最後一個固定參數的實際內存大小。在我的機器上直接用sizeof運算符來代替,對程序的運行結構也沒有影響。(後文將看到我自己的實現)。
3、va_start的定義為 &v+_INTSIZEOF(v) ,這里&v是最後一個固定參數的起始地址,再加上其實際佔用大小後,就得到了第一個可變參數的起始內存地址。所以我們運行va_start(ap, v)以後,ap指向第一個可變參數在的內存地址,有了這個地址,以後的事情就簡單了。
這里要知道兩個事情:
⑴在intel+windows的機器上,函數棧的方向是向下的,棧頂指針的內存地址低於棧底指針,所以先進棧的數據是存放在內存的高地址處。
(2)在VC等絕大多數C編譯器中,默認情況下,參數進棧的順序是由右向左的,因此,參數進棧以後的內存模型如下圖所示:最後一個固定參數的地址位於第一個可變參數之下,並且是連續存儲的。
|--------------------------|
| 最後一個可變參數 | ->高內存地址處
|--------------------------|
|--------------------------|
| 第N個可變參數 | ->va_arg(arg_ptr,int)後arg_ptr所指的地方,
| | 即第N個可變參數的地址。
|--------------- |
|--------------------------|
| 第一個可變參數 | ->va_start(arg_ptr,start)後arg_ptr所指的地方
| | 即第一個可變參數的地址
|--------------- |
|------------------------ --|
| |
| 最後一個固定參數 | -> start的起始地址
|-------------- -| .................
|-------------------------- |
| |
|--------------- | -> 低內存地址處
(4) va_arg():有了va_start的良好基礎,我們取得了第一個可變參數的地址,在va_arg()里的任務就是根據指定的參數類型取得本參數的值,並且把指針調到下一個參數的起始地址。
因此,現在再來看va_arg()的實現就應該心中有數了:
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
這個宏做了兩個事情,
①用用戶輸入的類型名對參數地址進行強制類型轉換,得到用戶所需要的值
②計算出本參數的實際大小,將指針調到本參數的結尾,也就是下一個參數的首地址,以便後續處理。
(5)va_end宏的解釋:x86平台定義為ap=(char*)0;使ap不再 指向堆棧,而是跟NULL一樣.有些直接定義為((void*)0),這樣編譯器不會為va_end產生代碼,例如gcc在linux的x86平台就是這樣定義的. 在這里大家要注意一個問題:由於參數的地址用於va_start宏,所以參數不能聲明為寄存器變數或作為函數或數組類型. 關於va_start, va_arg, va_end的描述就是這些了,我們要注意的 是不同的操作系統和硬體平台的定義有些不同,但原理卻是相似的.
三、可變參數在編程中要注意的問題
因為va_start, va_arg, va_end等定義成宏,所以它顯得很愚蠢, 可變參數的類型和個數完全在該函數中由程序代碼控制,它並不能智能 地識別不同參數的個數和類型. 有人會問:那麼printf中不是實現了智能識別參數嗎?那是因為函數 printf是從固定參數format字元串來分析出參數的類型,再調用va_arg 的來獲取可變參數的.也就是說,你想實現智能識別可變參數的話是要通過在自己的程序里作判斷來實現的. 例如,在C的經典教材《the c programming language》的7.3節中就給出了一個printf的可能實現方式,由於篇幅原因這里不再敘述。
四、小結:
1、標准C庫的中的三個宏的作用只是用來確定可變參數列表中每個參數的內存地址,編譯器是不知道參數的實際數目的。
2、在實際應用的代碼中,程序員必須自己考慮確定參數數目的辦法,如
⑴在固定參數中設標志-- printf函數就是用這個辦法。後面也有例子。
⑵在預先設定一個特殊的結束標記,就是說多輸入一個可變參數,調用時要將最後一個可變參數的值設置成這個特殊的值,在函數體中根據這個值判斷是否達到參數的結尾。本文前面的代碼就是採用這個辦法.
無論採用哪種辦法,程序員都應該在文檔中告訴調用者自己的約定。
3、實現可變參數的要點就是想辦法取得每個參數的地址,取得地址的辦法由以下幾個因素決定:
①函數棧的生長方向
②參數的入棧順序
③CPU的對齊方式
④內存地址的表達方式
結合源代碼,我們可以看出va_list的實現是由④決定的,_INTSIZEOF(n)的引入則是由③決定的,他和①②又一起決定了va_start的實現,最後va_end的存在則是良好編程風格的體現,將不再使用的指針設為NULL,這樣可以防止以後的誤操作。
4、取得地址後,再結合參數的類型,程序員就可以正確的處理參數了。理解了以上要點,相信稍有經驗的讀者就可以寫出適合於自己機器的實現來。
⑥ C語言中,關於stdarg. h可變參數應用,函數省略號前最後一個參數是幹啥用的它前面如果有其他
第一個作用是,用來確定被省略掉的參數起始地址,第二個作用通常是指定被省略掉參數的個數。
⑦ c語言標准函數庫的stdarg.h
va_list
type of object holding context information
void va_start(va_list ap, lastarg);
Initialisation macro which must be called once before any unnamed argument is accessed. Stores context information in ap. lastarg is the last named parameter of the function.
type va_arg(va_list ap, type);
Yields value of the type (type) and value of the next unnamed argument.
voidva_end(va_list ap);
Termination macro which must be called once after argument processing and before exit from function.
⑧ c語言...用法
C語言變參技術
概述
C語言中有一種長度不確定的參數,形如:"…",它主要用在參數個數不確定的函數中,我們最容易想到的例子是printf函數。
原型:
int printf( const char *format [, argument]... );
使用例:
printf("Enjoy yourself everyday!\\n");
printf("The value is %d!\\n", value);
這種可變參數可以說是C語言一個比較難理解的部分,這里會由幾個問題引發一些對它的分析。
注意:在C++中有函數重載(overload)可以用來區別不同函數參數的調用,但它還是不能表示任意數量的函數參數。
問題:printf的實現
請問,如何自己實現printf函數,如何處理其中的可變參數問題? 答案與分析:
在標准C語言中定義了一個頭文件<stdarg.h>專門用來對付可變參數列表,它包含了一組宏,和一個va_list的typedef聲明。一個典型實現如下:
typedef char* va_list;
#define va_start(list) list = (char*)&va_alist
#define va_end(list)
#define va_arg(list, mode)\\
((mode*) (list += sizeof(mode)))[-1]
自己實現printf:
#include <stdarg.h>
int printf(char* format, …)
{
va_list ap;
va_start(ap, format);
int n = vprintf(format, ap);
va_end(ap);
return n;
}
問題:運行時才確定的參數
有沒有辦法寫一個函數,這個函數參數的具體形式可以在運行時才確定?
答案與分析:
目前沒有"正規"的解決辦法,不過獨門偏方倒是有一個,因為有一個函數已經給我們做出了這方面的榜樣,那就是main(),它的原型是:
int main(int argc,char *argv[]);
函數的參數是argc和argv。
深入想一下,"只能在運行時確定參數形式",也就是說你沒辦法從聲明中看到所接受的參數,也即是參數根本就沒有固定的形式。常用的辦法是你可以通過定
義一個void
*類型的參數,用它來指向實際的參數區,然後在函數中根據根據需要任意解釋它們的含義。這就是main函數中argv的含義,而argc,則用來表明實際
的參數個數,這為我們使用提供了進一步的方便,當然,這個參數不是必需的。
雖然參數沒有固定形式,但我們必然要在函數中解析參數的意義,因此,理所當然會有一個要求,就是調用者和被調者之間要對參數區內容的格式,大小,有效性等所有方面達成一致,否則南轅北轍各說各話就慘了。
問題:可變長參數的傳遞
有時候,需要編寫一個函數,將它的可變長參數直接傳遞給另外的函數,請問,這個要求能否實現?
答案與分析:
目前,你尚無辦法直接做到這一點,但是我們可以迂迴前進,首先,我們定義被調用函數的參數為va_list類型,同時在調用函數中將可變長參數列表轉換為va_list,這樣就可以進行變長參數的傳遞了。看如下所示:
void subfunc (char *fmt, va_list argp)
{
...
arg = va_arg (fmt, argp); /* 從argp中逐一取出所要的參數 */
...
}
void mainfunc (char *fmt, ...)
{
va_list argp;
va_start (argp, fmt); /* 將可變長參數轉換為va_list */
subfunc (fmt, argp); /* 將va_list傳遞給子函數 */
va_end (argp);
...
}
問題:可變長參數中類型為函數指針
我想使用va_arg來提取出可變長參數中類型為函數指針的參數,結果卻總是不正確,為什麼?
答案與分析:
這個與va_arg的實現有關。一個簡單的、演示版的va_arg實現如下:
#define va_arg(argp, type) \\
(*(type *)(((argp) += sizeof(type)) - sizeof(type)))
其中,argp的類型是char *。
如果你想用va_arg從可變參數列表中提取出函數指針類型的參數,例如
int (*)(),則va_arg(argp, int (*)())被擴展為:
(*(int (*)() *)(((argp) += sizeof (int (*)())) -sizeof (int (*)())))
顯然,(int (*)() *)是無意義的。
解決這個問題的辦法是將函數指針用typedef定義成一個獨立的數據類型,例如:
typedef int (*funcptr)();
這時候再調用va_arg(argp, funcptr)將被擴展為:
(* (funcptr *)(((argp) += sizeof (funcptr)) - sizeof (funcptr)))
這樣就可以通過編譯檢查了。
問題:可變長參數的獲取
有這樣一個具有可變長參數的函數,其中有下列代碼用來獲取類型為float的實參:
va_arg (argp, float);
這樣做可以嗎?
答案與分析:
不可以。在可變長參數中,應用的是"加寬"原則。也就是float類型被擴展成double;char,
short被擴展成int。因此,如果你要去可變長參數列表中原來為float類型的參數,需要用va_arg(argp,
double)。對char和short類型的則用va_arg(argp, int)。
問題:定義可變長參數的一個限制
為什麼我的編譯器不允許我定義如下的函數,也就是可變長參數,但是沒有任何的固定參數?
int f (...)
{
...
}
答案與分析:
不可以。這是ANSI C 所要求的,你至少得定義一個固定參數。
這個參數將被傳遞給va_start(),然後用va_arg()和va_end()來確定所有實際調用時可變長參數的類型和值。
⑨ 【100分高分】如何用C語言畫齒輪
下面為C語言畫凸輪形狀程序
#include"stdarg.h"
#include"stdio.h"
#include"graphics.h"
#include"math.h"
#define H 60 /*最大行程*/
#define W 7.5 /*角速度(度/秒)*/
#define K 5 /*循環步驟*/
#define A1 45 /*各段角度*/
#define A2 210
#define A3 240
#define A4 360
#define X0 400 /*凸輪轉軸坐標*/
#define Y0 280
#define pi 3.14159
#define t pi/180 /*度--》弧度*/
main() /*主程序*/
{float e,ro,rr,p,so,dx,dy,st,ct,C3,C4,C5; /*變數說明*/
float s[200],ds[200],dv[200],da[200],x[200],y[200],xp[200],yp[200];
int a=DETECT,b,i=0,w=0;
/*----------------------------------------*/
initgraph(&a,&b,"");
e=10; /*偏心距*/
ro=90; /*基圓半徑*/
rr=20; /*滾子半徑*/
so=sqrt(ro*ro-e*e);
/*-------------------------------------------*/
C3=(300-5*(A1/W))/pow((pi/4),3);/*五次方高斯方和三個參數*/
C4=((26.25(A1/W))-1350)/(pow(pi/4),4);/*五次方高斯方和三個參數*/
C5=(180-3.75(A1/W))/pow((pi/4),5);/*五次方高斯方和三個參數*/
for(p=0;p<=A4;p+=K)
{if(p<=A1)/*第一段:等加速等減速運動*/
{s[i]=C3*pow(p,3)+C4*pow(p,4)+C5*pow(p,5);
ds[i]=3*C3*W*pow(p,2)+4*C4*W*pow(p,3)+5*C5*pow(p,4);
dv[i]=6*C3*W*W*p+12*C4*W*W*pow(p,2)+20*C5*w*w*pow(p,4);
}
if(p>A1&&p<=A2)/*第二段:直線運動*/
{s[i]=30+27.5*(p-A1)/(A2-A1);
ds[i]=27.5*W/(A2-A1);
dv[i]=0;
}
if(p>A2&&p<=A3)/*第三段:正弦加速的減速半段(前三段為推程)*/
{s[i]=57.5+5*((p-A2)/2/(A3-A2)-sin(pi*(p-A2)/(A3-A2))/(2*pi));
ds[i]=5*W(1-cos(pi*(p-A2)/(A3-A2))/2/(A3-A2));
dv[i]=5*pow(W,2)*2*pi*sin(pi*(p-A2)/(A3-A2))/4/(A3-A2)/(A3-A2);
}
if(p>A3)/*第四段:正弦加速(回程)*/
{s[i]=H*(1-(p-A3)/120+sin(pi*(p-A3)/60)/2/pi);
ds[i]=H*W/(A4-A3)*(cos(2*pi*(p-A3)/(A4-A3))-1);
dv[i]=-2*pi*H*W*W/pow((A4-A3),2)*sin(2*pi*(p-A3)/(A4-A3));
}
da[i]=(atan((ds[i]/(W*t)-e)/(so+s[i])))/(t); /*壓力角*/
x[i]=X0+(so+s[i])*sin(p*t)+e*cos(p*t); /*理論廓線坐標*/
y[i]=Y0+(so+s[i])*cos(p*t)-e*sin(p*t);
dx=(ds[i]-e)*sin(p*t)+(so+s[i])*cos(p*t); /*x微分*/
dy=(ds[i]-e)*cos(p*t)-(so+s[i])*sin(p*t); /*y微分*/
st=dy/sqrt(dx*dx+dy*dy); /*sin值*/
ct=dx/sqrt(dx*dx+dy*dy); /*cos值*/
xp[i]=x[i]+rr*st; /*外實際廓線坐標*/
yp[i]=y[i]-rr*ct;
i++;
}
/*----------------------------------------------------------*/
circle(X0,Y0,ro); /*畫基圓*/
circle(X0,Y0,e); /*畫偏距圓*/
for(w=0;w<A4/K; w++)
{ line(x[w],y[w],x[w+1],y[w+1]); /*畫理論廓線*/
line(xp[w],yp[w],xp[w+1],yp[w+1]); /*畫外實際廓線*/
circle(x[w],y[w],rr); /*畫滾子*/
}
circle(x[0],y[0],rr); /*滾子*/
circle(x[0],y[0],5); /*滾軸*/
circle(x[A1/K],y[A1/K],5); /*滾軸*/
circle(x[A2/K],y[A2/K],5);/*滾軸*/
circle(x[A3/K],y[A3/K],5);/*滾軸*/
circle(x[A4/K],y[A4/K],5);/*滾軸*/
line(X0+e,Y0,x[0],y[0]+50);/*3條導路方向線*/
line(X0+e*cos(60*t),Y0-e*sin(60*t),x[60/K],y[60/K]);
line(X0+e*cos(240*t),Y0-e*sin(240*t),x[240/K],y[240/K]);
arc(X0,Y0,0,50,100);/*凸輪轉向*/
line(X0+100,Y0,X0+100-5,Y0-15);/*轉向箭頭*/
line(X0+100,Y0,X0+100+3,Y0-15);/*轉向箭頭*/
getch();
/*----------------------運動線圖---------------------------------------*/
line(0,180,360,180);
line(0,240,360,240);
line(0,360,360,360);
line(0,0,0,480);
line(A1,0,A1,480);
line(A3,0,A3,480);
line(360,0,360,480);
for(w=0;w<A4/K;w++)
{line(w*K,180-s[w],(w+1)*K,180-s[w+1]);
line(w*K,240-ds[w]*4,(w+1)*K,240-ds[w+1]*4);
line(w*K,360-dv[w]*10,(w+1)*K,360-dv[w+1]*10);
getch();
/*--------------------------------數據列表--------------------------------*/
printf(" p s ds dv a \n");
printf("=============================\n");
for(w=0;w<=A4/K;w=w+3)
{printf("%4d%10.2f%8.2f%8.2f%10.2f\n",w*K,s[w],ds[w],dv[w],da[w]);}
getch();
}
}