第16章 C預(yù)處理器和C庫

C預(yù)處理器

預(yù)處理器: 就是在程序進(jìn)行編譯之前先做的事情,預(yù)處理器可以控制編譯的過程,列出要替換的內(nèi)容服球、指明要編譯的代碼行和影響編譯器其他方面的行為
注意:預(yù)處理器僅僅只是會(huì)替換內(nèi)容劝篷,而不會(huì)做實(shí)際的運(yùn)算。

#define預(yù)處理器指令

首先他由 3 個(gè)部分組成

  1. ‘#define’指令本身
  2. 選定的縮寫(也叫宏)通今。與變量的命名規(guī)則相同
  3. 替換列表或替換體
image.png
#include <stdio.h>
#define TWO 2
#define FOUR TWO * TWO

int main(void)
{
    int n;
    n = FOUR;  
     //注意這里并不是4
      //FOUR 先變成了了  TWO * TWO
      //然后   又替換成   2*2
      //之后便結(jié)束了粥谬,不會(huì)對(duì)他進(jìn)行下一步的運(yùn)算
}

在#define中使用參數(shù)


image.png
#include <stdio.h>
#define SQUARE(X) X*X
#define PR(X) printf("The result is %d.\n",X)

int main(void)
{
    int x = 5;
    int z;
    z = SQUARE(x);      /**
                            z = square(5);
                            z = 5 * 5;預(yù)處理結(jié)束下面不是預(yù)處理做的事情
                            所以
                            z = 25
                            */
    PR(z);              /***
                            printf("The result is %d.\n",25)
                            */
    z = SQUARE(2);          //
    PR(z);          //
    PR(SQUARE(x + 2));      /*
                                首先變成:
                                    printf("The result is %d.\n",SQUARE(x + 2))
                                    printf("The result is %d.\n", 5 + 2 * 5 + 2)
                                    所以結(jié)果是 17;
                                    不是49
                                    他只是替換上去不做運(yùn)算
                                    */

    PR(100 / SQUARE(2));//25
    PR(SQUARE(++x));//
}

文件包含:#include

兩種形式:
1. #include <stdio.h> //查找系統(tǒng)目錄
2.#include "mystuff.h" //查找當(dāng)前工作目錄
3.#include "/usr/biff/p.h" //查找/usr/biff目錄

條件編譯

用于防止重復(fù)的創(chuàng)建和包含

  1. #ifdef辫塌、#else 漏策、#\endif指令
#ifdef MAVIS
#include "horse.h"      //如果已經(jīng)用#define定義了MAVIS, 則執(zhí)行下面的指令
#define STABLES 5       
#else
#include "cow.h"        //如果沒有定義則執(zhí)行這里
#define STABLES 15
#endif                  //結(jié)束
  1. #ifndef指令 和#ifdef類似臼氨,如果是未定義的則執(zhí)行

  2. #if和#elif指令

#if defined (IBMPC)     //較新的編譯器可以這么寫
    #include "ibmpc.h"  //這種方法和#ifdef VAX 一樣不過這種寫法可以使用elif
#elif defined (VAX)
    #include "vax.h"
#endif                  //結(jié)束

編程練習(xí)

1

/**
 * 自己定義一個(gè)頭文件
*/

#ifndef JIHHHH_H_
#define JIHHHH_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#endif

2

/**
 * 用一個(gè)宏‘函數(shù)’計(jì)算兩數(shù)的調(diào)和平均數(shù)
*/

#include "JIHHHH.h"

#define HARMEAN(x, y)   (1 / ((1 / (x) + 1 / (y)) / 2))
 
int main(void)
{
    printf("%lf ", HARMEAN(5.6, 6.3));
    return 0;
}

3

image.png
/**
 * 計(jì)算x y掺喻。
*/

#include "JIHHHH.h"
#include <math.h>

struct coordinate
{
    float x;
    float y;
    float r;
    float A;
};

struct coordinate count(struct coordinate coor);

int main(void)
{
    struct coordinate coordinates;

    puts("Please Enter:");
    scanf("%f %f", &coordinates.r, &coordinates.A);
    coordinates.A *= 3.14 / 180;
    coordinates = count(coordinates);
    printf("x: %.2f y: %.2f ", coordinates.x, coordinates.y);
}

struct coordinate count(struct coordinate coor)
{
    coor.x = coor.r * cos(coor.A);
    coor.y = coor.r * sin(coor.A);
    return coor;
}

4

/**
*  ANSI 庫這樣描述colok()函數(shù)的特性:
*  #include <time.h>
*  clock_t clock(void);
*  這里,clock_t是定義在time.h中的類型。該函數(shù)返回處理器時(shí)間巢寡,其單位取決于實(shí)現(xiàn)(如果
*  處理器時(shí)間不可用或無法表示喉脖,該函數(shù)返回-1)。然而抑月,CLOCKS_PER_SEC(也定義在time.h
*  中)是每秒處理器時(shí)間單位的數(shù)量树叽。因此,兩個(gè)clock()返回的值的差值除以 CLOCKS_PER_SEC
*  得到兩次調(diào)用之間經(jīng)過的秒數(shù)谦絮。在進(jìn)行除法運(yùn)算之前题诵,把值的類型強(qiáng)制轉(zhuǎn)換成double類型,可以
*  將時(shí)間精確到小數(shù)點(diǎn)以后层皱。編寫一個(gè)函數(shù)性锭,接受一個(gè)double類型的參數(shù)表示時(shí)間的延遲數(shù),然后
*  在這段時(shí)間運(yùn)行一個(gè)循環(huán)叫胖。編寫一個(gè)簡(jiǎn)單的程序測(cè)試該函數(shù)草冈。
*/

#include "JIHHHH.h"
#include <time.h>

void stop_time(double n);

int main(void)
{
   double num;
   puts("Please enter stop time");
   scanf("%lf", &num);
   stop_time(num);

   return 0;
}

void stop_time(double n)
{
   clock_t start_t;

   start_t = clock();
   while ((n - (double)(clock() - start_t) / CLOCKS_PER_SEC)> 0) ;

   printf("%.2f", n);
}

5

/**
 *  編寫一個(gè)函數(shù)接受這些參數(shù):內(nèi)含int類型元素的數(shù)組名、是數(shù)組的大小和一個(gè)代表選取次數(shù)的
 *  值瓮增。該函數(shù)從數(shù)組中隨機(jī)選擇指定數(shù)量的元素怎棱,并打印他們。每個(gè)元素只能選擇一次(模擬抽獎(jiǎng)
 *  數(shù)字或挑選陪審團(tuán)成員)绷跑。另外拳恋,如果你的實(shí)現(xiàn)有time()或類似的函數(shù),可在srand()中
 *  使用這個(gè)函數(shù)的輸出來初始化隨機(jī)數(shù)生成器rand()砸捏。編寫一個(gè)簡(jiǎn)單的程序測(cè)試該函數(shù)谬运。
*/

#include "JIHHHH.h"
#include <time.h>

void lucky_draw(int st[], int nums, int next);

int main(void)
{
    int st[10];
    for (int i = 0; i < 10; i++)
    {
        st[i] = i + 1;
    }
    srand((unsigned int)time(0));

    lucky_draw(st, 10, 5);
    return 0;
}

void lucky_draw(int st[], int nums, int next)
{
    int temp[10] = {0};
    int i;
    int tem;
    for ( i = 0; i < next;/*i++ 也能這么寫*/ )
    {
        tem = rand() % nums;
        if (temp[tem])
        {
            //i--;
            continue;
        }
        temp[tem] = 1;
        printf("%d ", st[tem]);
        i++;//防止重復(fù)時(shí)依舊++i 最后選的數(shù)字少
    }
}

6

/**
 *  修改程序清單16.17,使用struct names元素(在程序清單16.17后面的討論中定義過)垦藏,而不是
 *  double類型的數(shù)組梆暖。使用較少的元素,并用選定的名字顯示初始化數(shù)組掂骏。
*/

#include "JIHHHH.h"
#include <time.h>
#define NUM 40

typedef struct
{
    char first[NUM];
    char last[NUM];
}NAMES;

void fillarray(NAMES pst[], int n);
void showarray(const NAMES pst[], int n);
int mycomp(const void * p1, const void * p2);

int main(void)
{
    NAMES staff[NUM];

    fillarray(staff, NUM);
    puts("Random list:");
    showarray(staff, NUM);
    qsort(staff, NUM, sizeof(NAMES), mycomp);
    puts("\nSorted list:");
    showarray(staff, NUM);
    return 0;
}

void fillarray(NAMES pst[], int n)
{
    int i, j;
    int count;
    srand((unsigned int) time(0));
    for ( i = 0; i < n; i++)
    {
        count = rand() % 10 + 1;
        for ( j = 0; j < count; j++)
        {
            pst[i].first[j] = rand() % 26 + 'a';
            pst[i].last[j] = rand() % 26 + 'a';
        }
        pst[i].first[j] = '\0';     //一定要加不然就不是字符串了式廷。
        pst[i].last[j] = '\0';
    }
}

void showarray(const NAMES pst[], int n)
{
    int i;
    for ( i = 0; i < n; i++)
    {
        printf("%10s %-10s ", pst[i].first, pst[i].last);
        if (i % 5 == 4)
            putchar('\n');
    }
    
}

int mycomp(const void * p1, const void * p2)
{
    const NAMES * ps1 = (const NAMES *) p1;
    const NAMES * ps2 = (const NAMES *) p2;
    int res;
    res = strcmp(ps1->first, ps2->first);
    if (res != 0)
        return res;
    else
        return strcmp(ps1->last, ps2->last);
}

7

/**
 *  new_d_array()函數(shù)接受一個(gè)int類型的參數(shù)和double類型的參數(shù)。該函數(shù)返回一個(gè)指針芭挽,
 *  指向由malloc()分配的內(nèi)存塊滑废。int類型的參數(shù)指定了動(dòng)態(tài)數(shù)組中的元素個(gè)數(shù),double類型的
 *  值用于初始化元素(第1個(gè)值賦給第1個(gè)元素袜爪,以此類推)蠕趁。編寫show_array()和new_d_array()
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void show_array(const double ar[], int n);
double * new_d_array(int n, ...);

int main(void)
{
    double * p1;
    double * p2;

    p1 = new_d_array(5, 1.2, 2.3, 3.4, 4.5, 5.6);
    p2 = new_d_array(4, 100.0, 20.00, 8.08, -1890.0);
    show_array(p1 , 5);
    show_array(p2, 4);
    free(p1);
    free(p2);
}

void show_array(const double ar[], int n)
{
    int i;
    for ( i = 0; i < n; i++)
    {
        printf("%.2lf ", ar[i]);
    }
    printf("\n");
    
}

double * new_d_array(int n, ...)
{
    va_list ap;
    double * p = (double *)malloc(n * sizeof(double));
    int i;

    va_start(ap, n);
    for ( i = 0; i < n; i++)
    {
        p[i] = va_arg(ap, double);
    }
    va_end(ap);

    return p;
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辛馆,隨后出現(xiàn)的幾起案子俺陋,更是在濱河造成了極大的恐慌豁延,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腊状,死亡現(xiàn)場(chǎng)離奇詭異诱咏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)缴挖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門袋狞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人映屋,你說我怎么就攤上這事苟鸯。” “怎么了棚点?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵早处,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我瘫析,道長(zhǎng)砌梆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任贬循,我火速辦了婚禮咸包,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘甘有。我一直安慰自己,他們只是感情好葡缰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布亏掀。 她就那樣靜靜地躺著,像睡著了一般泛释。 火紅的嫁衣襯著肌膚如雪滤愕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天怜校,我揣著相機(jī)與錄音间影,去河邊找鬼。 笑死茄茁,一個(gè)胖子當(dāng)著我的面吹牛魂贬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裙顽,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼付燥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了愈犹?” 一聲冷哼從身側(cè)響起键科,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后勋颖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嗦嗡,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年饭玲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侥祭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咱枉,死狀恐怖卑硫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蚕断,我是刑警寧澤欢伏,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站亿乳,受9級(jí)特大地震影響硝拧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜葛假,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一障陶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧聊训,春花似錦抱究、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至勋磕,卻和暖如春妈候,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挂滓。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國打工苦银, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赶站。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓幔虏,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親贝椿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子所计,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容