程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 學點C語言(34):函數 - 關於變量

學點C語言(34):函數 - 關於變量

編輯:關於C語言

1. 局部變量:

局部變量也叫自動變量,它聲明在函數開始,生存於棧,它的生命隨著函數返回而結束.

#include <stdio.h>

int main(void)
{
  auto int i = 9; /* 聲明局部變量的關鍵字是auto;因可以省略,幾乎沒人使用 */

  printf("%d\n",i);
  getchar();
  return 0;
}

2. 全局變量:

全局變量聲明在函數體外,一般應在函數前; 每個函數都可以使用它,不過全局變量應盡量少用.

#include <stdio.h>

void add(void);
void mul(void);

int gi = 3; /* 全局變量 */

int main(void)
{
  printf("%d\n",gi); /* 3 */

  add();
  printf("%d\n",gi); /* 5 */

  mul();
  printf("%d\n",gi); /* 10 */

  getchar();
  return 0;
}

void add(void) {
  gi += 2;
}

void mul(void) {
  gi *= 2;
}

全局變量會被初始化為空,而局部變量在沒有賦值前是一個垃圾值:

#include <stdio.h>

int gi; /* 全局變量 */

int main(void)
{
  int i; /* 句柄變量 */

  printf("%d,%d\n",gi,i);

  getchar();
  return 0;
}

當全局變量與局部變量重名時,使用的是局部變量:

#include <stdio.h>

int a = 111,b = 222;

int main(void)
{
  int a = 123;
  printf("%d,%d\n",a,b); /* 123,222*/

  getchar();
  return 0;
}

3. static 關鍵字:

用 static 關鍵字修飾的局部變量是靜態局部變量;

靜態局部變量存值如同全局變量,區別在於它只屬於擁有它的函數; 它也會被初始化為空.

#include <stdio.h>

void fun1(void);
void fun2(void);

int main(void)
{
  int i;

  for (i = 0; i < 10; i++) fun1();
  printf("---\n");
  for (i = 0; i < 10; i++) fun2();

  getchar();
  return 0;
}

void fun1(void) {
  int n = 0;    /* 一般的局部變量 */
  printf("%d\n",n++);
}

void fun2(void) {
  static int n;   /* 靜態局部變量; 會被初始化為空 */
  printf("%d\n",n++);
}

用 static 關鍵字修飾的全局變量是靜態全局變量; 靜態全局變量只能用於定義它的單元.

//譬如在File1.c裡面定義了:
static int num = 99; /* 去掉前面的 static 其他單元才可以使用 */

//在File2.c裡使用:
#include <stdio.h>

extern int num;

int main(void)
{
  printf("%d\n",num);

  getchar();
  return 0;
}

用靜態變量記錄函數被調用的次數:

#include <stdio.h>

int fun(void);

int main(void)
{
  int i;
  for (i = 0; i < 10; i++) {
    printf("函數被調用了%2d次;\n",fun());
  }
  getchar();
  return 0;
}

int fun(void) {
  static int n;
  return ++n;
}

4. 寄存器變量(register):

書上說寄存器變量會盡量把變量放到寄存器(而不是棧或堆),從而加快存取速度,我試了一下,效果一般般.

#include <stdio.h>
#include <time.h>

#define TIME 1000000000

int m,n = TIME; /* 全局變量 */

int main(void)
{
  time_t start,stop;

  register int a,b = TIME; /* 寄存器變量 */
  int x,y = TIME;     /* 一般變量  */

  time(&start);
  for (a = 0; a < b; a++);
  time(&stop);
  printf("寄存器變量用時: %d 秒\n",stop - start);

  time(&start);
  for (x = 0; x < y; x++);
  time(&stop);
  printf("一般變量用時: %d 秒\n",stop - start);

  time(&start);
  for (m = 0; m < n; m++);
  time(&stop);
  printf("全局變量用時: %d 秒\n",stop - start);

  getchar();
  return 0;
}

4. extern 關鍵字:

使用外部全局變量應該用extern 重新聲明一下;

如果不使用 extern,將是重新定義;

在鏈接階段,同一程序中不同單元的全局變量是共用的所以不能重新定義;

本例為了省事並沒有涉及另一個文件,只是把變量放在文件尾模擬了一下.

另外,extern 主要還是用於函數.

#include <stdio.h>

extern int g1;

int main(void)
{
  extern int g2;

  printf("%d,%d\n",g1,g2);
  getchar();
  return 0;
}

int g1 = 77;
int g2 = 88;

5. volatile 關鍵字:

程序在使用變量時,特別是連續多次使用變量時,一般是載入寄存器,直接從寄存器存取,之後再還回內存;

但如果此變量在返回內存時,假如內存中的值已經改變了(從外部修改了)怎麼辦?

為了避免這種情況的發生,可以用 volatile 說明此變量,以保證變量的每次使用都是直接從內存存取.

但這樣肯定會影響效率,幸好它並不常用.

另外: 如果 const volatile 同時使用,這表示此變量只接受外部的修改.

#include <stdio.h>

volatile int num = 123;

int main(void)
{
  printf("%d\n",num);
  getchar();
  return 0;
}

6. restrict 關鍵字:

restrict 有點和 volatile 相反; 不過 restrict 只是對指針.

好像 C++Builder 2009 並不支持它,暫時無法測試.

返回“學點C語言 - 目錄”

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved