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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

《C语言程序设计教程》(一)

發布時間:2023/12/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《C语言程序设计教程》(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

      • 標識符規則
      • 常量變量
        • 變量的初始化
      • 數據類型
        • 實型數據
        • 字符型數據
      • 基本表達式和運算符
        • sizeof
        • 類型強制轉化
        • printf格式控制字符
        • 附加格式符
        • putchar
        • 標準輸入
        • scanf調用注意點
        • getchar
        • 條件運算條件表達式
        • if條件
        • for
        • breakcontinue
        • 判斷是否是素數
        • 數組
        • scanf函數
        • getchar方法
        • 字符數組
        • 字符串
        • 字符串的輸入輸出
        • 字符串處理函數
        • 指針
          • 訪問類型
          • 指針變量定義
          • 指針的比較
        • 指針和一維數組關系
          • 利用指針遍歷一維數組的兩種方法
        • 2維數組指針
          • 二維數組的指針變量
        • 字符串指針
        • 字符串指針變量使用的注意點
        • 函數返回值是指針
        • 指向函數的指針
        • 二級指針
        • 指針函數
        • 數組指針
        • 指針tip
        • 結構體
        • 結構體變量的成員引用操作
        • 結構體變量的初始化
        • 結構體與數組
        • 結構體如何訪問數組成員
        • 結構體與指針
        • 結構體鏈表
          • 動態內存分配
          • 內存釋放
        • 共用體
          • 共用體的定義
          • 共用體的訪問對象
          • 結構體和共用體的聯合使用
        • 枚舉
        • typedef
        • 函數的申明與調用
        • 參數傳遞
        • 局部變量全局變量
        • 變量的存儲類別

標識符規則

  • 標識符只能由字母、數字、下劃線組成。
  • 標識符的有效長度是1-255。
  • 標識符的第一個字符必須是字母或者數字。
  • 標識符在大小寫是區分。
  • 標識符不能與c的關鍵字相同。
  • 常量、變量

    int c= 7; #define PAI = 3.1415926;//常量的標識符全好是大寫。

    變量的初始化

    可以多個同類型的一起賦值

    int c= 7,b = 6;

    數據類型

    實型數據

    也稱為浮點數。兩種表現形式:

    • 十進制小數
    • 指數形式
    double c = 1.6e3;//這里用大小的e無所謂一般形式:aEna為十進制數,n為階碼,表示指數,必須是十進制整數,正負都可以。

    需用的注意以下幾點:

  • 階碼之前必須有十進制的數。
  • 指數不能為小數。
  • 在實型計算中,不區分單精度還是雙精度,都按照double,除非,你在數字后面指定了f或F,則認為是float。

    double 提供16位有效數字,就是7位整數。
    float提供7位有效數字,就是16位整數。

    字符型數據

    字符常量是用單引號括起來的字符。

    • 只有用單引號括起來的才是字符常量,用雙引號或者其他符號括起來不是字符常量。
    • 字符常量只能是單個字符,不能是多個,轉義的除外。
    • 字符常量以ASCLL碼存儲,范圍0-255,字符常量是以ASCLL
    • 等價的整數值就行運算。

      轉義字符

    是一種特殊的字符常量,以\開頭,有特定的含義。

    \n 回車換行
    \t 橫跳下一個制表符
    \b 退格
    \r 回車
    \f 走紙換頁
    \ 反斜線\
    \’ 單引號
    \” 雙引號

    字符變量

    char o = 'a';

    一個字符變量占一個字節的分配空間。
    一個中文漢字=兩個字符,占2個字節。

    字符串常量

    字符串常量是由一對雙括號括起來,系統會自動在每個字符串結束后面加一個字符串結束標志’\0’。

    字符常量和字符串常量區別

  • 字符串由單括號括起來,字符串常量是由雙括號括起來的
  • 字符串只能是單個字符(除轉義外),字符串常量可以含0個或多個。
  • 在c語言中,可以把一個字符常量賦值給字符變量,但是不能把一個字符串常量賦值給字符串變量,因為在
    c中,沒有定義相應的字符串變量,在后面會講到用字符數組來存放一個字符串常量。

    字符串常量的字節數,是字符串的字符個數+1,因為還有一個字符串結束標識符也占一個字節。

    基本表達式和運算符

    在c語言中一些基本的,我就不講。

    sizeof是用來結束數據的字節數。

    /:是除法運算,如果參加運算的都是整型,那么結果就是整型,舍去小數;但是如果參加的運算有一個是實型,那么結果就是double。

    %:求余運算,要求參加運算的量都是整型,然后取兩數的余數。

    sizeof

    這個功能是求數據在內存中所占的字節數。

    int a = sizeof(10);printf("%d",a);

    類型強制轉化

    double c = (double)(a+b);

    printf格式控制字符

  • %d 以十進制輸出帶符號整數,不包含正數符號。
  • %o 以八進制輸出無符號的整數,不輸出前綴0。
  • %x 以十六進制輸出無符號整數,不輸出OX。
  • %u 以十進制輸出無符號整數。
  • %f 以小數形式輸出單、雙精度實數。
  • %e 以指數形式輸出單、雙精度實數。
  • %c 輸出單個字符。
  • %s 輸出字符串。
  • 附加格式符

  • %-d %-c %-f 結果是左對齊,默認不加是右對齊。
  • %+d 輸出數字的時候帶正負號。
  • 空格 在輸出正數時前面加空格,輸出負數前面加負號。
  • %ld %lf 用來輸入長整型或者雙精度數字。
  • %md 代表整數輸出幾位數字。
  • %m.nf 代表浮點數小數點后面n位。
  • putchar

    可以用來輸入字符常量和字符變量。

    putchar('a');

    標準輸入

    scanf(“格式控制字符”,地址表列); //地址列表中給出的各變量的地址,地址是通過取地址符&后面跟變量名來獲取的。

    scanf調用注意點

  • 在輸入數據的時候,兩個數據一般用空格、enter、tab分開。
  • 如果在各式控制字符中出現非格式控制字符,你需要在控制臺也要原樣輸進去。
  • 在輸入數據的時候,不要指定精度。
  • getchar

    這個函數執行的時候,會等待用戶來輸入一個字符。

    條件運算、條件表達式

    a>b?a:b

    if條件

    if的條件不一定是條件表達式為true,也可以是一個常量只要不是0,就可以的。

    for

    使用for循環的時候,如果3個判斷條件沒有時,也要要分號隔開。

    for(;(c = getchar())!='\n';)

    break、continue

    break:是跳出、結束循環,continue:是繼續循環。break使用范圍,就是在while、do….while、for、switch。而continue是結束本次循環 ,只能在while、do….while、for中使用,如果在while和do…while中使用,遇到continue會直接回到while后面的判斷,而執行for的時候就直接到for循環的第三個條件表達式。

    判斷是否是素數

    素數又稱質數,是指不能被其他的整數整除的自然數,其算法思想:用n去依次除以2~~n-1之間的每一個數,如果每次整除,則n是素數;只要有一次實現整除,則判斷不是質數,這個就是優化,沒必要一直看到底。

    int n,i,flag;i = 2;flag = 0;n = 0;printf("請隨便輸入一個數:\n");scanf("%d",&n);for(i=2;i<=n-1;i++){if(n%i==0){flag =1;break;}}if(flag==1){printf("這個數不是質數");}else{printf("這個是質數");}

    數組

    c語言中的數組長度不可以用變量去定義。

    scanf函數

    利用scanf輸入數據,一次數據輸入的結束是通過,空格,Enter,Tab 來結束一次,特別是在循壞中。

    getchar()方法

    這個方法是用來輸入字符的,并且返回這個字符的ascll編碼,需要注意這個方法每次輸入只能是一個字符,如果輸入多個,則只接收第一個字符,另外,如果多個字符輸入在一行,它的結束標志,就是回車,如果每輸入一個字符換行,那么連續兩次回車,就是結束標志。此外它比scanf輸入字符好,因為空格它同樣能處理,而scanf不行,它會當做結束符。

    字符數組

    char a[10]={'a''b''c''d'};如果字符數組的長度大于字符個數,那么系統默認會給其他數組元素為'\0'如果你在定義的時候,指定字符,那么可以不顯示指定字符數組的長度,編譯器會自動知道。

    字符串

    c語言的字符串是指有限個組成的字符序列,它是以字符數組的形式存放,并且以’\0’作為字符串的結束標志。

    char s[10] ={"hello"}

    如果字符數組的長度大于字符個數,那么系統默認會給其他數組元素為’\0’

    處理字符數組時候,一旦遇到’\0’就表示字符串已經結束,如果字符串有多個’\0’,那么會認為在第一個’\0’之前的是有效字符。

    字符串和字符數組最顯著的區別,就是字符數組中,如果數組長度等于字符個數,那么是不需要添加’\0’

    在計算字符串的長度時,‘\0’是不參加計算的。

    如果你在定義的時候,指定字符,那么可以不顯示指定字符數組的長度,編譯器會自動知道。

    只要字符串沒有字符,那么系統會自動加上’\0’

    如果你一直給字符串賦值,那么strlen是變的,這個一定要在后面注意,這點和java是不一樣。

    字符串的輸入輸出

    char a[20];char b[20];scanf("%s",a);//使用字符控制符去輸入,字符串必須是存放在字符數組中printf("%s",a);//打印的時候也是直接數組名gets(b);//傳入數組名,這種方法和上面比,每次只能輸入一個字符串,上面可以是多個。puts(b);//輸出完成后,會自動換行。

    注意如何利用scanf輸入多個字符串:

    scanf("%s%s",a,c);

    一般的在scanf遇到一個%s,就是一次,千萬不能理解這個是一次輸入兩個,那就不對了,不要看他們是同一行。

    字符串處理函數

    char c1[80]={"sdada"};char c2[80]={"hsdkjass"};int i =0;//strcat(c1,c2);//將后面的字符串連接到前面來//后面的字符串可以是數組名,//也可以是字符串常量,但是字符串1必須是字符串數組名。//strcpy(c1,c2);//將后面的字符串復制到前面字符數組//后面的字符串可以是數組名,//也可以是字符串常量,但是字符串1必須是字符串數組名。//c1="sdasda";錯誤的//c1 = c2;錯誤的//int r = strcmp(c1,c2);//字符串比較函數//返回一個整數值,如果是0,代表兩個字符串相等//如果是正整數,代表前面字符串大//如果是負整數,代表前面的字符串小。//比較的實質,是從開始比較每一個字符的ascll//這兩個參數可以是字符數組或者字符常量//兩個字符串之間比較絕對不可以用> < == !=int t = strlen(c1);//返回字符數組的實際長度不包含結束標識符。//sizeof是返回參數的內存空間,也就是字節數。//該方法的參數可以是字符數組或者字符常量

    指針

    程序運行時,所有的程序和數據都是放在內存中,內存是以字節為單位的連續的存儲空間,每一個內存都有一個編號,稱為內存地址。

    一個字節就是一個存儲單元。

    變量的地址是由編譯器動態分配的,對用戶是無關的。

    指針:就是指向某個對象(可能是簡單變量、數組、函數)所占用的存儲單元的首地址,這里說明一下,一個對象,開辟的空間一定是連續的,所以,指針就是指向這個連續空間的首地址。

    指針變量:存放變量地址的變量。

    訪問類型
  • 直接訪問
  • 直接通過變量名來訪問。

  • 間接訪問
  • 先找到存放該變量的地址的變量,先找到地址,在訪問。

    指針變量定義
    int *i_pointer;//表示指向整型變量的指針變量。

    其中* 表示定義指針變量,前面的類型,也稱基類型,表示指針變量所指向的變量的類型。

    指針變量只能指向定義時所規定類型的變量。

    不可以將任何非地址的值,賦給指針變量,除了0(NULL)必須是大寫。

    int *p;*p = 0;*p =NULL;

    指針變量定義好了之后,必須要初始化,否則變量值不確定。

    指針初值,可以賦3種形式

  • &變量名
  • &數組元素
  • 數組名
  • int *p;int a;int b[5];p = &a;p =b;p = b[0];

    *是間接訪問運算符,它是先訪問指針變量,然后在訪問它指向的變量的值。

    指針變量的算術運算。

    指針p+n,是指指針p原來指向的數據單元格之后的第n個數據單元格,而數據單元格和數據類型有關。

    在這里,我要說明一下,數據存儲單元和內存單元的對比。

    數據存儲單元格是人們簡化內存單元格的。

    int *p;int a;p=&a;//假如a的地址是2000,則p+1 = 2004//原因int的數據類型占4個字節

    所以在這,你就要理解指針變話p++,就是使p指向下一個空間。

    指針的比較

    在同一段連續的存儲空間,如果p的地址值小于q的地址值,那么結果為1,反之為0。

    指針和一維數組關系

    數組名就是指針,是數組的首地址,這個叫做靜態指針。

    int a[10];int *p;p =a;//p = &a[0]兩種等價

    根據指針運算p+1,就是指向數組中的下一個元素。

    利用指針遍歷一維數組的兩種方法
    for(i=0;i<5;i++){scanf("%d",p+i);//根據i的變化,改變指針指向的地址}for(i=0;i<5;i++){printf("%d",*(p+i));}for(p=a;p<a+5;p++){scanf("%d",p);//指針初始值指向數組的首地址,指針的地址范圍應該是控制數組首地址加上數組的個數,自增改變指針的地址。}for(p=a;p<a+5;p++){printf("%d",*p);}

    在一維數組中

    a[i] =p[i] = p+i = a+i//都表示是指向某一個元素

    2維數組指針

    從二維數組來看,a是二維數組名,a就代表了整個二維數組的首地址。a+1代表第一行。

    a[0]+1,就代表第一列。

    故:
    //在這里,我們把對二維數組的處理,當成多個1維數組來處理。

    a[i][j] = *(a[i]+j)=*(*(a+i)+j)

    在二維數組有兩個概念

  • 列地址
  • a[i][j] = *(a[i]+j)=*(*(a+i)+j)都表示列地址
  • 行地址
  • a 代表二維數組首行 a+1 第一行 a+2 第二行
    • 行地址前就加*就變為列地址。
    • 列地址前加&就變為行地址。
    • 只有在列地址前加*才能訪問該二維數組的值。
    二維數組的指針變量
    int a[2][2];int (*p)[2];//指針變量的括號一定不能少p =a;int i,j;for(i =0;i<2;i++){for(j = 0;j<2;j++){scanf("%d",(*(p+i)+j));}}for(i =0;i<2;i++){for(j = 0;j<2;j++){printf("%d",*(*(p+i)+j));}}

    字符串指針

    用指針變量操作字符串,指針變量指向的是字符串的首地址,也就是第一個字符地址。

    char str[]="helloworld";char *p;//定義字符串指針p = str;//指向字符串的第一個字符的首地址int i = 0;for(i = 0;*p!='\0';p++){printf("%c",*p);printf("%s",p);//注意這種操作打印字符串是通過指向第一個指針的*地址*,這里就不是值了。一直到字符串結束,這種比較方便,后面使用的比較多。}

    字符串指針變量使用的注意點

    char c1[10]="hello";char *pa;pa="hello"//表示指針變量指向的是字符串的第一個字符的首地址pa+2//指向字符串的第3個字符地址,指針變量可以指向字符串的任意位置,可以隨意改變指針變量的值c1作為字符串的數組名,可以作為首地址,可以進行加減,但是不能賦給c1,因為數組名是地址常量,不可以改變。(這點和前面使用一樣,需要注意)

    函數返回值是指針

    定義函數,返回類型是指針。

    定義類型

    數據類型 * 函數名 (參數表) int *max(){int i = 0;int k = 0;static int data[]={1,2,34,9,0,17,8,7};for(i=0;i<8;i++){if(data[i]>data[k]){k = i;}}return &data[k]; }void test19(){int *p;p = max();//需要定義的指針變量去接收函數返回值,這里定義的指針變量需要和函數定義的返回類型一致。printf("%d",*p);}

    指向函數的指針

    指向函數的指針,實際上就是函數執行的入口,函數名就代表中該函數的入口地址。

    數據類型 (* 指針變量名) (參數表)

    對函數的調用

    (* 指針變量名) (實參)

    例子:

    int max1(int data[],int n){int i = 0;int k = 0;for(i=0;i<n;i++){if(data[i]>data[k]){k = i;}}return data[k]; }void test20(){int a[4] ={2,9,8,0};int (*p)(int a[],int n);//定義指針函數int m = 0;p = max1;//在此之前,你需要申明一下max1函數,這里我申明了指向函數的入口m = (*p)(a,4);//執行函數printf("%d",m);}

    二級指針

    定義:一個指針變量存放的是另一個指針變量地址。

    int i = 78;int *p;int **pp;//定義二級指針p = &i;pp = &p;printf("%d",i);printf("%d",*p);printf("%d",**pp);

    指針函數

    定義: 數組中的每一個元素都是指針類型。

    char *a[100]={"hello","world"};int i = 0;for(i = 0;i<2;i++){printf("%s",a[i]);//a[0]就是指向第一個數組元素的(首地址)指針,所以直接打印字符串//在前面說過,如果指針指向的是字符串的首地址,打印出來,則是整個字符串}

    數組指針

    定義:指向整個數組的指針。

    int a[4]={1,2,3,4};int (*p)[4];p = a;//這個是指向整個數組的指針,這里注意區分之前用的多的是指向數組的第一個元素的指針。int a[2][3]={1,2,3,4,5,6};int (*p)[3] = a;//這里的指針是數組中存在每一個元素首地址的指針集合,而這里每一個元素換成一行的首地址,這里需要重點理解一下。為什么可以指向一個二維數組呢,原因很簡單,你可以這樣理解,二維數組其實,我們可以看成2行的1維數組,p[0]就是指向1,2,3的首地址1,p[1]就是指向2,3,4的首地址2,然后p[0]+2,就是指針移動指向3。printf("%d",*(p[1]));printf("%d",*(*(p+1)+1));//訪問第二行的第二個元素。

    指針tip

    在前面我們說過,數組名是靜態指針,不可以進行自加自減,但是可以執行a+1等運算操作,注意一下。

    結構體

    我們前面學習了,可以利用數組進行同一種數據類型的處理,而我們也是有可能把不同的數據類型作為一個整體,這時,就可以選用結構體來處理這種數據。

    結構體作為一種數據結構,是不太方便好去遍歷,我們可以通過鏈表去實現對結構體的遍歷。鏈表是可以通過結構體去實現的。

    struct date{int year;int months;int days;};struct date birth;//定義一個結構體date的變量//需要注意的是定義結構體類型,本身不占用存儲空間,//只是說明了結構體組織形式,只有定義結構體;變量,才占用空間。//在本例中,結構體占的空間,就是3個int所占空間之和。struct date birth1,birth2,birth3//定義多個結構體變量,用逗號隔開。struct date{int year;int months;int days;} birthday;//可以在定義結構體類型時,一起定義結構體變量。

    下面這是我們處理結構體定義常用方法。利用typeof定義新的結構體類型名代替定義的結構體類型名。

    typedef struct date{int year;int months;int days;} Date;Date birthday;//這樣定義結構體變量就簡單,也好記。struct date birthday兩種等價

    結構中定義中,可以嵌套結構體變量。

    typedef struct date{int year;int months;int days;struct birthday1;} Date;

    結構體變量的成員引用操作

    .是結構體成員運算符,在所有優先級中是最高的。

    struct StudentDate{int year;int month;int day;};struct Student{int num;char name[20];char sex[10];float score;struct StudentDate birthday;};struct Student s;//定義結構體變量scanf("%d",&s.num);//如果直接是結構體//的成員,直接通過.運算符來進行操作printf("%d",s.num);scanf("%d",&s.birthday.year);printf("%d",s.birthday.year);//如果是內嵌結構體成員,//則需要通過外部的結構體變量去引//用內部結構體變量的成員,這里需要注意內部結構體變量已經申明在外部結構體中,不需要在定義了。

    結構體變量的初始化

    struct StudentDate{int year;int month;int day;} a={1996,9,10};struct StudentDate{int year;int month;int day;};struct StudentDate a ={199,9,10};//定義結構體變量并賦值
    • 一定不能在結構體內部初始化。
    • 賦值的時候一定要和結構體中定義的順序一致。
    • 如果結構體中有內嵌,初始化和外部結構體一起初始化,按照順序即可。

    結構體與數組

    結構體中成員可以是數組類型

    struct student{int a[10];};struct student s;scanf("%d",&s.a[1]);printf("%d",s.a[1]);

    結構體數組,即該數組中每一個元素都是結構體類型。

    struct student{int a[10];};struct student s[3];//定義了一個包含3個元素//的數組,并且每一個元素都是結構體類型scanf("%d",&s[2].a[1]);printf("%d",s[2].a[1]);

    結構體數組初始化:

    struct student{int a[10];} s[3]={{12},{22},{4}};

    結構體如何訪問數組成員

    這里演示的是通過結構體指針去訪問,通過結構體變量訪問比較簡單,自行看。

    struct Student {int num;char name[20];float score[5]; };p->score[0]

    結構體與指針

  • 結構體成員是指針
  • struct test{int data;int *p;};struct test t;t.data =100;int i;t.p = &i;//通過結構變量//去調用指針變量去指向一//個int類型的變量*t.p = 88;//這個需要注意,之前說過.運算符是優先級最高的。printf("%d",t.data);printf("%d",i);
  • 指向結構體變量的指針
  • struct date{int year;};struct date d;struct date *p;p=&d;(*p).year = 1990;//可能會有人認為為啥這里//不是p,p只是一個地址,我//們需要通過p指向的地址值,來操作。printf("%d",(*p).year);//由于優先級,括號不能少printf("%d",p->year);//簡化操作訪問成員操作,不過這個操作符只能和指針一起使用。printf("%d",d.year);
  • 指向結構體數組的指針
  • struct test{int s;} a[2]={{1},{2}};struct test *p;p = a;//數組名就是首地址for(;p<a+2;p++){printf("%d",*p);}

    結構體鏈表

    結構體成語可以指向本結構體類型的指針,可以用這個來構造比較復雜的數據結構體,鏈表。

    鏈表是由稱為節點的元素組成,節點多少根據需要來定。

    每一個節點包含:

  • 數據部分,可以存放多個數據成員。
  • 指針部分,可以存放下一個節點的地址。
  • 鏈表結構特點:鏈表有一個首指針,它指向鏈表的第一個節點,最后一個節點稱為 “表尾”,表尾節點的指針為null。

    動態內存分配

    malloc:從內存中申請一塊指定字節大小的連續空間,返回該存儲地址的首地址作為函數的返回值,如果申請失敗,說明沒有足夠的空間可以分配,返回空指針。

    int *p;p = (int *)malloc(sizeof(int));//通過該函數動態申請了一個int類型大小if(p!=null){*p = 23;}else{exit(1);//exit是系統標準函數,作用是關閉//所有打開文件,并終止程序執行。參數為0是正常結束,非0//表示不正常結束。}

    由于該函數返回的是void類型的指針,所以需要進行強制類型轉換,轉換為指針變量所應該指向的數據類型。

    內存釋放

    free()函數。

    注意點:

  • free函數和malloc函數必須配對使用,申請的內存空間,不用的時候一定要釋放。
  • 加入兩個指針同時指向同一個地址,如果只釋放其中一個指針,這時另外一個指針就不能訪問這塊存儲區。
  • 共用體

    有時,我們希望在不同的時刻把不同的類型數據存放到同一個內存單元中。

    共用體的定義
    union un{float f;int i ;char c;};//定義共用體union un u;//定義共用體變量union un1{float f;int i ;char c;}u;//定義共用體變量和類型

    注意點:

  • 盡管共用體與結構體在定義上類似,但是在內存分配上有本質的區別。
  • 共用體成員占相同的起始地點,所占內存長度等于最長的成員所占內存長度。
  • 共用體的訪問對象

    通過.運算。

    u.c = 'a';

    如果是定義的是指針,那么同樣可以通過—>去訪問對象。

    • 由于共用體各個成員都共用一段存儲空間,所以在任意的時刻,只能有一種數據類型存放在共用體變量中,也就是說任意一個時刻,只有一個成員有意義。
    • 在引用共用體變量時,必須保證其存儲類型的一致性,在一次程序運行時,一個成員操作了申明類型,在下一次中,還必須是這種類型。
    • 共用體不能作為函數參數
    • 共用體不能初始化,原因很簡單,如果初始化的話,那不就是說他們同時有意義,這不符合共合體的使用。
    結構體和共用體的聯合使用

    共用體可以出現在結構體中,結構體也可以出現在共用體中。

    union un{int fivescore;float hunscore; };struct Student{int num;char name[20];char sex;int type;union un scrore;//這里將共用體定義在結構體中,需要定義共用體變量。(如果這里是定義結構體,那么這里就需要定義結構體變量) };p1->scrore.hunscore = hunscore1;//訪問內部共用體變量的時候,就需要注意,定義結構體指針,通過—>來訪問結構體的變量,因為這時得到的是共用體的變量,通過共用體變量名訪問成員,就必須是.運算符。

    枚舉

    枚舉類,一個變量在很小的范圍內取值,則可以使用枚舉類。

    enum Bool{Flase,True};//定義枚舉類型enum Bool bool;//定義枚舉變量enum Bool1{Flase1,True1} bool1; //在定義枚舉類型和枚舉變量printf("%d",True);//打印枚舉量的值,雖然定義和結構體很類似,但是訪問成員不是通過.運算。

    注意點:

    • 枚舉元素是常量,有固定的數值,按枚舉的順序分別是 整數0,1,2,3;不能被用作變量,即不可以出現在賦值號的左邊。
    True = 1;//是不允許的
    • 不能有兩個元素相同的枚舉元素,枚舉元素也不能與其他變量同名。
    • 枚舉元素作為常數處理,遇到枚舉元素,編譯器會將其中第一個元素賦值為0,然后依次疊加。自己可以修改為枚舉元素指定值,然后排在該枚舉元素后面的值,將自動一次疊加1。

    typedef

    用于用戶自己定義類型說明符。

    typedef int INT;INT a = 5;//等價于int a =5typedef char NAME[20];NAME a1;//等價于 char a1[20];typedef struct Student{int num;float score;} S;S student;//等價于struct Student studenttypedef char *p;p p1;//等價于 char * p1

    這個使用你只需要,找到原始的元素定義的變量,直接用這個變量來簡化申明你自己定義的變量。

    函數的申明與調用

    函數聲明

    c語言編譯,是從上到下,如果被調函數不在調用函數之前,則必須顯示申明,否則報錯。

    函數類型 被調函數名(形參表列)//這種必須包括形參類型、變量名函數類型 被調函數名(形參類型表列)//這種只是形參類型,沒有變量名

    有些標準的庫函數,只需要導入頭文件即可。

    參數傳遞

    分類:

  • 值傳遞
  • 地址傳遞
  • 當形參為簡單變量時,在函數調用過程中,數據只能由實參傳給形參,而不能由形參傳回給實參,這種數據傳遞方式是單向,無論形參如果修改值,都不會影響實參的值。

    數組作為參數傳遞:

  • 當數組元素即元素下標作為參數傳遞,數組元素都是簡單元素,形參和實參占用不同的存儲空間,實參與形參之間的數據傳遞是單向值傳遞,不會改變原有數組的元素值。
  • 當用數組名作為參數傳遞,數組名代表元素的首地址,這時,實參與形參共用一塊內存空間。形參中的數組值改變,會影響原有的數組,這種是地址傳遞。要實現地址傳遞,形參和實參都必須是類型相同 的數組名,后面用指針作為函數傳遞,也是地址傳遞。
  • 局部變量、全局變量

    局部變量:作用域僅限于函數內有效,離開該函數則沒有用。

    • 在參數傳遞時,形參就是該調用函數的局部變量。
    • 在不同的函數中,可以使用相同的變量名,互相不干擾。

    全局變量:是指定義在函數外的變量,作用從定義的位置到本源程序文件尾。

    變量的存儲類別

    變量存儲方式:

  • 靜態存儲方式:是指在程序運行期間分配固定的存儲空間,
  • 動態存儲方式:是指在程序運行期間根據需要進行動態分配存儲空間。每執行完程序一次,就會釋放變量空間
  • 變量存儲類別

  • auto變量。在c語言中飯時未加存儲類別的變量均視為自動變量。自動變量屬于動態存儲,只有在被調用的時候才分配內存單元,程序結束后,立即釋放存儲單元。
  • static變量。又稱之為靜態變量。在函數局部定義中的變量,函數執行,該值仍然保留,等待下次該函數執行,除非該函數在也不執行,就釋放。

    靜態變量在編譯時,只賦初值一次,賦值為0。而自動變量,每次執行完函數,都會重新賦值。自動變量未賦值,它的值是不確定的。
    雖然靜態變量的值,函數執行結束,變量空間未釋放,但靜態變量不可以被其他函數調用。

  • 寄存器變量。如果一個函數頻繁的使用某個變量計算,那么就可以使用寄存器變量。寄存器變量,只能給自動變量和形參定義,不可以將全局、靜態變量定義為寄存器變量。由于計算機的寄存器數目多,所以不宜定義太多寄存器變量。

  • extern(外部變量),這個可以類比是全局變量,但是全局變量是在該定義之后才可以使用該變量,那么在之前使用,則需要用extern申明,就可以當成全局變量使用,否則會產生語法錯誤。

  • 總結

    以上是生活随笔為你收集整理的《C语言程序设计教程》(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

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