亚洲一级免费看,特黄特色大片免费观看播放器,777毛片,久久久久国产一区二区三区四区,欧美三级一区二区,国产精品一区二区久久久久,人人澡人人草

C語(yǔ)言

C語(yǔ)言函數(shù)的定義

時(shí)間:2025-03-07 08:03:17 C語(yǔ)言 我要投稿

C語(yǔ)言函數(shù)的定義

  引導(dǎo)語(yǔ):函數(shù)表示每個(gè)輸入值對(duì)應(yīng)唯一輸出值的一種對(duì)應(yīng)關(guān)系。這種關(guān)系使一個(gè)集合里的每一個(gè)元素對(duì)應(yīng)到另一個(gè)(可能相同的)集合里的唯一元素。以下是小編分享給大家的C語(yǔ)言函數(shù)的定義,歡迎參考學(xué)習(xí)!

  一、函數(shù)的定義

  一個(gè)函數(shù)包括函數(shù)頭和語(yǔ)句體兩部分。

  函數(shù)頭由下列三不分組成:

  函數(shù)返回值類型

  函數(shù)名

  參數(shù)表

  一個(gè)完整的函數(shù)應(yīng)該是這樣的:

  函數(shù)返回值類型 函數(shù)名(參數(shù)表)

  {

  語(yǔ)句體;

  }

  函數(shù)返回值類型可以是前面說(shuō)到的某個(gè)數(shù)據(jù)類型、或者是某個(gè)數(shù)據(jù)類型的指針、指向結(jié)構(gòu)的指針、指向數(shù)組的指針。指針概念到以后再介紹。

  函數(shù)名在程序中必須是唯一的,它也遵循標(biāo)識(shí)符命名規(guī)則。

  參數(shù)表可以沒(méi)有也可以有多個(gè),在函數(shù)調(diào)用的時(shí)候,實(shí)際參數(shù)將被拷貝到這些變量中。語(yǔ)句體包括局部變量的聲明和可執(zhí)行代碼。

  我們?cè)谇懊嫫鋵?shí)已經(jīng)接觸過(guò)函數(shù)了,如abs(),sqrt(),我們并不知道它的內(nèi)部是什么,我們只要會(huì)使用它即可。

  這一節(jié)主要講解無(wú)參數(shù)無(wú)返回值的函數(shù)調(diào)用。

  二、函數(shù)的聲明和調(diào)用

  為了調(diào)用一個(gè)函數(shù),必須事先聲明該函數(shù)的返回值類型和參數(shù)類型,這和使用變量的道理是一樣的(有一種可以例外,就是函數(shù)的定義在調(diào)用之前,下面再講述)。

  看一個(gè)簡(jiǎn)單的例子:

  void a(); /*函數(shù)聲明*/

  main()

  {

  a(); /*函數(shù)調(diào)用*/

  }

  void a() /*函數(shù)定義*/

  {

  int num;

  scanf(%d,&num);

  printf(%d ,num);

  }

  在main()的前面聲明了一個(gè)函數(shù),函數(shù)類型是void型,函數(shù)名為a,無(wú)參數(shù)。然后在main()函數(shù)里面調(diào)用這個(gè)函數(shù),該函數(shù)的作用很簡(jiǎn)單,就是輸入一個(gè)整數(shù)然后再顯示它。在調(diào)用函數(shù)之前聲明了該函數(shù)其實(shí)它和下面這個(gè)程序的功能是一樣的:

  main()

  {

  int num;

  scanf(%d,&num);

  printf(%d ,num);

  }

  可以看出,實(shí)際上就是把a(bǔ)()函數(shù)里面的所有內(nèi)容直接搬到main()函數(shù)里面(注意,這句話不是絕對(duì)的。)

  我們前面已經(jīng)說(shuō)了,當(dāng)定義在調(diào)用之前時(shí),可以不聲明函數(shù)。所以上面的程序和下面這個(gè)也是等價(jià)的:

  void a()

  {

  int num;

  scanf(%d,&num);

  printf(%d ,num);

  }

  main()

  {

  a();

  }

  因?yàn)槎x在調(diào)用之前,所以可以不聲明函數(shù),這是因?yàn)榫幾g器在編譯的時(shí)候,已經(jīng)發(fā)現(xiàn)a是一個(gè)函數(shù)名,是無(wú)返回值類型無(wú)參數(shù)的函數(shù)了。

  那么很多人也許就會(huì)想,那我們何必還要聲明這一步呢?我們只要把所有的函數(shù)的定義都放在前面不就可以了嗎?這種想法是不可取的,一個(gè)好的程序員總是在程序的開(kāi)頭聲明所有用到的函數(shù)和變量,這是為了以后好檢查。

  前面說(shuō)了,在調(diào)用之前,必須先聲明函數(shù),所以下面的做法也是正確的(但在這里我個(gè)人并不提倡)。

  main()

  {

  void a();

  a();

  }

  v  oid a()

  {

  int num;

  scanf(%d,&num);

  printf(%d ,num);

  }

  一般來(lái)說(shuō),比較好的程序書(shū)寫(xiě)順序是,先聲明函數(shù),然后寫(xiě)主函數(shù),然后再寫(xiě)那些自定義的函數(shù)。

  既然main()函數(shù)可以調(diào)用別的函數(shù),那么我們自己定義的函數(shù)能不能再調(diào)用其他函數(shù)呢?答案是可以的。看下面的例子:

  void a();

  void b();

  main()

  {

  a();

  }

  void a()

  {

  b();

  }

  void b()

  {

  int num;

  scanf(%d,&num);

  printf(%d ,num);

  }

  三、C語(yǔ)言讀書(shū)筆記--函數(shù)

  先來(lái)看看函數(shù)的一般形式,嘗試寫(xiě)一個(gè)加法的函數(shù):

  思路是這樣的:首先得有頭文件,頭文件之后就得寫(xiě)主函數(shù),主函數(shù)的內(nèi)部應(yīng)該就是加法的過(guò)程,我們將所有加法的語(yǔ)句都拿出來(lái)組成一個(gè)函數(shù)。代碼如下:

  #include

  int add(int a, int b);

  int main()

  {

  int result = add(3,5);

  printf("sum is %d ", result);

  return 0;

  }

  int add(int a, int b)

  {

  int sum;

  sum = a+b;

  return sum;

  }

  這是一個(gè)最簡(jiǎn)單的函數(shù),描述了一個(gè)加法函數(shù)的定義和調(diào)用的過(guò)程。

  int add(int a, int b) 成為函數(shù)的首部。

  有了首部之后,就得考慮一件事情,將首部復(fù)制之后,加上一個(gè)分號(hào),粘貼在主函數(shù)之前,作為函數(shù)的原型聲明。試想,我們?cè)谥骱瘮?shù)里邊是不是要先定義變量result才能使用result?那么函數(shù)的道理也是一樣的,當(dāng)程序運(yùn)行到主函數(shù)中語(yǔ)句“int result = add(3,5);”的時(shí)候,如果向上沒(méi)有尋找到add()的定義,那么編譯器一定就會(huì)報(bào)錯(cuò)。所以要不然添加函數(shù)的原型聲明,要不然就將函數(shù)的定義直接寫(xiě)在主函數(shù)之前。

  函數(shù)首部int add(int a, int b)中的第一個(gè)int,即add之前的這個(gè)int稱為函數(shù)的類型。表明這個(gè)函數(shù)將要返回一個(gè)整數(shù)類型的值。這個(gè)類型可以是C語(yǔ)言中任何被允許的數(shù)據(jù)類型,包括void,意為無(wú)返回值類型,即這個(gè)函數(shù)不需要返回任何的值。

  函數(shù)首部int add(int a, int b)中的add稱為函數(shù)的名字,簡(jiǎn)稱函數(shù)名。

  函數(shù)首部int add(int a, int b)中int a和int b稱為函數(shù)的形式參數(shù)。這里形式參數(shù)理論上可以有無(wú)窮多個(gè),當(dāng)然,現(xiàn)實(shí)情況下3-5個(gè)就已經(jīng)算是很多了;形式參數(shù)中,即使a和b都是int類型的,也要分別定義才行;形式參數(shù)可以在函數(shù)中直接使用,無(wú)須再次定義;形式參數(shù)是用來(lái)告訴調(diào)用者,你應(yīng)該給我傳遞來(lái)什么樣子的數(shù)據(jù),我好利用你給我的數(shù)據(jù)在函數(shù)中進(jìn)行計(jì)算。

  int add(int a, int b){}中的{}就是函數(shù)體的內(nèi)容了。函數(shù)需要進(jìn)行的所有的操作都要放在這對(duì)大括號(hào)中。想必大家也看到了函數(shù)體中最后有一條語(yǔ)句是return,這條語(yǔ)句起到的作用就是返回函數(shù)計(jì)算的結(jié)果,在這個(gè)程序中就是將加法的結(jié)果返回給主函數(shù)。需要注意的是,函數(shù)的類型和返回值的類型必須嚴(yán)格一致!

  函數(shù)的定義到此為止,接下來(lái)講講函數(shù)的調(diào)用方式。只要定義好函數(shù),通過(guò)函數(shù)名(實(shí)際參數(shù)1,實(shí)際參數(shù)2,實(shí)際參數(shù)n)這種方式就可以調(diào)用函數(shù)了。例如主函數(shù)中的“int result = add(3,5);”,就是調(diào)用了add函數(shù)。這里,3和5稱為實(shí)際參數(shù),即你究竟想讓函數(shù)幫你計(jì)算哪兩個(gè)數(shù)的加法結(jié)果,你就在這個(gè)括號(hào)里邊寫(xiě)哪幾個(gè)數(shù)字。必須要嚴(yán)格遵守的規(guī)定:實(shí)際參數(shù)和形式參數(shù)必須一一對(duì)應(yīng),數(shù)量應(yīng)該相同,類型也保持一致。

  理解了這幾點(diǎn)之后,一個(gè)基本的函數(shù)就已經(jīng)可以寫(xiě)出來(lái)了。接下來(lái)來(lái)個(gè)題目嘗試一下:

  輸入精度e,使用公式求π的近似值,精確到最后一項(xiàng)的絕對(duì)值小于e。公式:π=1-1/3+1/5-1/7+...

  代碼:

  //首先得有頭文件

  #include

  #include//后邊要使用到fabs絕對(duì)值函數(shù)

  //然后就是主函數(shù)了

  int main(void)

  {

  double pi, e; //定義所需變量

  double f_pi(double e); //原型聲明。函數(shù)名只要符合命名規(guī)則即可 //因?yàn)橐笮∮趀,所以也將這個(gè)e傳遞過(guò)去

  printf("enter e: "); //輸入的提示

  scanf("%lf", &e); // double類型的e對(duì)應(yīng)%lf,記住不要缺少&

  printf("pi=%lf ", f_pi(e) ); // 函數(shù)返回的是個(gè)double類型的值,直接輸出

  return 0;

  }

  double f_pi(double e) //函數(shù)首部,形參和實(shí)參一定要對(duì)應(yīng),可以重名

  {

  int denominator, flag;

  double item, sum;

  //請(qǐng)注意“先定義,然后賦初值再使用”的好習(xí)慣!!!

  flag = 1; //負(fù)責(zé)變換正負(fù)符號(hào)的變量

  denominator = 1; //分母初值為1,第一項(xiàng)的1為1/1

  item=1.0; //存放每一項(xiàng)的值

  sum=0;

  while(fabs(item)>=e) //滿足條件就循環(huán)

  {

  item=flag*1.0/denominator; //計(jì)算每一項(xiàng)的值。flag控制符號(hào)

  //1.0必須寫(xiě)出小數(shù)位,否則整項(xiàng)就變成一個(gè)整型值

  sum+=item; //累加

  flag = -flag; //符號(hào)正負(fù)切換

  denominator = denominator + 2;//分母遞增

  }

  return sum; //sum的類型和函數(shù)的類型必須一致

  }

  函數(shù)的定義和調(diào)用其實(shí)并不難理解,相信很多人困擾在參數(shù)的傳遞上,接下來(lái)總結(jié)一下函數(shù)參數(shù)傳遞的幾種方式:

  正常的參數(shù)調(diào)用,例如int、float、double等一一對(duì)應(yīng)的傳遞。

  無(wú)參數(shù),也無(wú)返回值。例如下列代碼就只是為了輸出一些語(yǔ)句。這種做法在語(yǔ)法上是被允許的,但是并不推薦這么寫(xiě)。

  void printf()

  {

  printf("hello world!");

  }

  3. 參數(shù)是數(shù)組的名字。我們知道數(shù)組的名字是個(gè)地址,那么如果實(shí)參是數(shù)組名的話,我們可以將形參設(shè)置成指針,指向?qū)崊鬟f過(guò)來(lái)的數(shù)組的首地址。

  4. 參數(shù)是指針。如果實(shí)參是指針,那么形參肯定也得是指針。保持類型一致即可,然后在函數(shù)內(nèi)部再對(duì)指針進(jìn)行操作。

  5. 參數(shù)是結(jié)構(gòu)體。如果實(shí)參是結(jié)構(gòu)體,一般來(lái)說(shuō)我們使用結(jié)構(gòu)體指針來(lái)做形參比較合適。

  還是在此分割一下吧,說(shuō)了這么多,可能很多人在問(wèn)問(wèn)什么函數(shù)定義這么麻煩,還要定義函數(shù),直接都寫(xiě)在main函數(shù)中多方便?

  非也!

  C語(yǔ)言是一個(gè)過(guò)程化的語(yǔ)言,C語(yǔ)言中的主函數(shù)其實(shí)是用來(lái)主導(dǎo)程序的進(jìn)程和數(shù)據(jù)的流動(dòng)方向的。如果將主函數(shù)寫(xiě)的過(guò)于復(fù)雜,我們閱讀程序的結(jié)構(gòu)就會(huì)非常的費(fèi)力。

  四、C語(yǔ)言中函數(shù)回調(diào)

  什么是回調(diào)函數(shù)?

  簡(jiǎn)而言之,回調(diào)函數(shù)就是一個(gè)通過(guò)函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用為調(diào)用它所指向的函數(shù)時(shí),我們就說(shuō)這是回調(diào)函數(shù)。

  為什么要使用回調(diào)函數(shù)?

  因?yàn)榭梢园颜{(diào)用者與被調(diào)用者分開(kāi)。調(diào)用者不關(guān)心誰(shuí)是被調(diào)用者,所有它需知道的,只是存在一個(gè)具有某種特定原型、某些限制條件(如返回值為int)的被調(diào)用函數(shù)。

  如果想知道回調(diào)函數(shù)在實(shí)際中有什么作用,先假設(shè)有這樣一種情況,我們要編寫(xiě)一個(gè)庫(kù),它提供了某些排序算法的實(shí)現(xiàn),如冒泡排序、快速排序、shell排序、shake排序等等,但為使庫(kù)更加通用,不想在函數(shù)中嵌入排序邏輯,而讓使用者來(lái)實(shí)現(xiàn)相應(yīng)的邏輯;或者,想讓庫(kù)可用于多種數(shù)據(jù)類型(int、float、string),此時(shí),該怎么辦呢?可以使用函數(shù)指針,并進(jìn)行回調(diào)。

  回調(diào)可用于通知機(jī)制,例如,有時(shí)要在程序中設(shè)置一個(gè)計(jì)時(shí)器,每到一定時(shí)間,程序會(huì)得到相應(yīng)的通知,但通知機(jī)制的實(shí)現(xiàn)者對(duì)我們的程序一無(wú)所知。而此時(shí),就需有一個(gè)特定原型的函數(shù)指針,用這個(gè)指針來(lái)進(jìn)行回調(diào),來(lái)通知我們的程序事件已經(jīng)發(fā)生。

  下面是自己寫(xiě)的一個(gè)簡(jiǎn)單的回調(diào)函數(shù),相比其他的那些復(fù)雜的代碼,這個(gè)更容易理解:

  #include

  #include

  void perfect(int n)

  {

  int i=1;

  int count=0;

  for(i=1;i<n;i++)

  {

  if(0==n%i)

  {

  count+=i;

  }

  }

  if(count==n)

  printf("%d是完數(shù) ",n);

  else printf("%d不是完數(shù) ",n);

  }

  void myCallback(void (*perfect)(int ),int n)

  {

  perfect(n);

  }

  int main()

  {

  int n;

  printf("請(qǐng)輸入一個(gè)正整數(shù) ");

  scanf("%d",&n);

  myCallback(perfect,n);

  return 0;

  }

  五、C語(yǔ)言中的刷新和定位函數(shù)

  一.fflush

  1.fflush的原型如下:

  intfflush(FILE *stream);

  2.當(dāng)需要立即把輸出緩沖區(qū)的數(shù)據(jù)進(jìn)行物理寫(xiě)入時(shí),應(yīng)該使用這個(gè)函數(shù)。例如調(diào)用fflush函數(shù)保證調(diào)試信息實(shí)際打印出來(lái),而不是保存在緩沖區(qū)中直到以后才打印。

  二.定位函數(shù)

  1.在正常情況下,數(shù)據(jù)以線性的方式寫(xiě)入,這意味著后面寫(xiě)入的數(shù)據(jù)在文件中的位置是在以前所有寫(xiě)入數(shù)據(jù)的后面。C同時(shí)支持隨機(jī)訪問(wèn)I/O,也就是以任意順序訪問(wèn)文件的不同位置。隨機(jī)訪問(wèn)是通過(guò)在讀取或?qū)懭肭,先定位到文件中需要的位置?lái)實(shí)現(xiàn)的。

  2.定位函數(shù)原型:

  1>long ftell(FILE*stream);

  2>intfseek(FILE *steam,long offset,intfrom);

  3.ftell函數(shù)返回流的當(dāng)前位置。即:下一個(gè)讀取或?qū)懭雽⒁_(kāi)始的位置距離文件起始位置的偏移量。該函數(shù)允許保存一個(gè)文件的當(dāng)前位置。

  1>在二進(jìn)制流中,這個(gè)值就是當(dāng)前位置距離文件起始位置之間的字節(jié)數(shù)。

  2>在文本流中,這個(gè)值表示一個(gè)位置,但它并不一定準(zhǔn)確地表示當(dāng)前位置和文件起始位置之間的字符數(shù),因?yàn)橛行┫到y(tǒng)將對(duì)行末字符進(jìn)行翻譯轉(zhuǎn)換。但是,ftell函數(shù)返回的值總是可以用于fseek函數(shù)中,作為一個(gè)距離文件起始位置的偏移量。

  4.fseek函數(shù)允許你一個(gè)流中定位。這個(gè)函數(shù)將改變下一個(gè)讀取或?qū)懭氩僮鞯奈恢。它的?1個(gè)參數(shù)是需要改變的流。它的第2和第3個(gè)參數(shù)標(biāo)識(shí)文件中需要定位的位置。

  1>試圖定位到一個(gè)文件的起始位置之前是一個(gè)錯(cuò)誤。定位到文件尾并進(jìn)行寫(xiě)入將擴(kuò)展這個(gè)文件。定位到文件尾之后并進(jìn)行讀取將導(dǎo)致返回一條“到達(dá)文件尾”的信息。

  2>在二進(jìn)制流中,從SEEK_END進(jìn)行定位可能不被支持,所以應(yīng)該避免。

  3>在文本流中,如果from是SEEK_CUR或SEEK_END,offset必須是零。如果from是SEEK_SET,offset必須是一個(gè)從同一個(gè)流中以前調(diào)用ftell所返回的值。

  5.用fseek改變一個(gè)流的位置會(huì)帶來(lái)三個(gè)副作用。

  1>首先,行末指示字符被清除。

  2>其次,如果在fseek之前使用ungetc把一個(gè)字符返回到流中,那么這個(gè)被退回的字符會(huì)被丟棄,因?yàn)樵诙ㄎ徊僮饕院螅辉偈恰跋乱粋(gè)字符”。

  3>最后,定位允許你從寫(xiě)入模式切換到讀取模式,或者回到打開(kāi)的流以便更新。

【C語(yǔ)言函數(shù)的定義】相關(guān)文章:

C語(yǔ)言自定義函數(shù)08-09

編程函數(shù)的定義之C語(yǔ)言05-16

C語(yǔ)言程序中函數(shù)的定義05-28

C語(yǔ)言中如何定義函數(shù)式宏02-15

C語(yǔ)言宏定義07-01

C語(yǔ)言變量定義07-29

淺談C語(yǔ)言函數(shù)03-28

C語(yǔ)言函數(shù) atoi()03-23

C語(yǔ)言函數(shù)的含義06-15