1. 程式人生 > >C語言基礎知識易錯點總結

C語言基礎知識易錯點總結

1.定義了變數一定要儘快賦一個值,我們叫初值。因為定義變數實際上是在記憶體中開闢了一塊新空間,但空間裡也許有之前留下的東西(資料)。所以,如果你不用初值把這塊空間覆蓋掉,很容易在後面出現莫名其妙的問題。

2.在各種不同系統中,字元型別(char)都佔1Bytes(8bits)。

3.float型別賦值時,常量的後面要加"f",因為不加這個"f" 計算機會分配一個double型別大小的空間,而前面的變數型別又是float,這時就會報錯。

4.

char str[] = "ABCD"

字串的儲存比較特殊,系統會自動在字串後面加入一個'\0'符號。這個符號在轉義字元表中可以找到,代表空字元。計算機用它表示一個字串的結束。因此,"ABCD"在記憶體中其實是"ABCD\0"。

5.巨集常量的表示方法相當於把定義中常量位置的東西原封不動地寫在常量名的地方

#include <stdio.h>

#define sum 5 + 1;

void main()
{
    int a = 2 * sum;
    printf("%d", a);
}

請問,這段程式輸出的結果是多少。如果你答12就錯了,應該是11。

6.隱式型別轉換基本原則:

  • 在賦值語句中, 等號右邊的值轉換為等號左邊變數所屬的型別
  • 不同型別混合計算時,結果型別為資料型別級別較高的
  • 所有的浮點預算都是以double進行的

7.不申請第三個變數數值交換

運用<<或>>符號可以進行乘二除二運算

a = a ^ b;
b = a ^ b;
a = a ^ b;

8.逗號運算子的運算優先順序

","運算子用於將多個表示式串在一起, ","運算子的左邊總不返回,右邊表示式的值才是整個表示式的值

9.運算子優先順序:

  1. ()(小括號) [](陣列下標) .(結構成員) ->(指標型結構成員)
  2. !(邏輯非) .(位取反) -(負號) ++(加1) --(減1) &(變數地址)
  3. *(指標所指內容) type(函式說明) sizeof(長度計算)
  4. *(乘) /(除) %(取模)
  5. +(加) -(減)
  6. <<(位左移) >>(位右移)
  7. <(小於) <=(小於等於) >(大於) >=(大於等於)
  8. ==(等於) !=(不等於)
  9. &(位與)
  10. ^(位異或)
  11. |(位或)
  12. &&(邏輯與)
  13. ||(邏輯或)
  14. ?:(?表示式)
  15. = += -=(聯合操作)
  16. ,(逗號運算子)
10.getchar()和putchar()的用法:
  • getchar(): 將使用者輸入的字元輸出到標準輸出裝置(螢幕)。按【Enter】鍵後,getchar()函式才會讀入第一個字元,並返回該字元常量。putchar(): 用來輸出指定的單一字元。
  • putchar():用來輸出指定的單一字元。
注意:由於緩衝區的讀取特性,當用戶由鍵盤鍵入字元時,計算機並不會馬上處理,而會暫存到系統的緩衝區(Buffter)內。到按【Enter】鍵後,getchar()函式才會讀入緩衝區的第一個字元。而其它字元繼續保留在緩衝區,等待下一個讀取字元/字串的函式來讀入。請看下面這段程式碼:
#include <stdio.h>

int main()
{
    char c, s[20];
    printf("Enter a string: ");
    c = getchar();
    printf("Read the remaining from the buffer\n");
    scanf("%s", s);

    putchar(c);
    putchar('\n');
    printf("%s \n", s);

    return 0;
}

執行結果:


11.

  • getche(): 該函式會由鍵盤輸入一個字元,返回給呼叫者,並在螢幕上顯示讀入的字元。由於它並不讀取緩衝區的字元,只要使用者輸入字元,getche()函式會立刻讀取,而不需等待按【Enter】鍵。通常用於程式中只需使用者輸入一個字元,即可往下繼續執行的情形。
  • getch(): 它與getche()的區別是,getch()不需將所輸入的字元顯示到螢幕上。
#include <stdio.h>

int main()
{
    char c1, c2;

    printf("Press any key to exit");
    c1 = getche();
    putchar('\n');

    printf("Press any key once more to exit");
    c2 = getch();
    putchar('\n');

    printf("The character getche() read: %c \n", c1);
    printf("The character getch() read: %c \n", c2);

    return 0;
}

執行結果:

11.在利用下標訪問陣列a時,如果下標大於等於陣列長度,系統會報錯,叫做陣列訪問越界。這是必須要牢記的。

12.字元陣列總結:

  • ' '表示一個空格字元
  • 如果大括號中的字元個數大於陣列長度,系統會報錯
  • 如果大括號中的字元個數小於陣列長度,則將這些字元從陣列第一個元素開始向後排列,其餘的元素儲存為空字元(即 '\0' )
13.字串的初始化

最常用的字串初始化方法是:

char str[ ] = "I am happy";

注意:上述這種字元陣列的整體賦值只能在字元陣列初始化時使用,不能用於字元陣列的賦值,字元陣列的賦值只能對其元素一一賦值,下面的賦值方法是錯誤的

char str[ ];
str = "I am happy";

不是用單個字元作為初值,而是用一個字串作為初值。顯然,這種方法更直觀方便。

注意:陣列str的長度不是10,而是11,這點請務必記住,因為字串常量"I am happy"的最後由系統自動加上一個'\0'因此,上面的初始化與下面的初始化等價

char str[ ] = {'I',' ','a','m',' ','h','a','p','p','y','\0'};

而不與下面的等價

char str[ ] = {'I',' ','a','m',' ','h','a','p','p','y'};

前者的長度是11,後者的長度是10。

說明:字元陣列並不要求它的最後一個字元為'\0'。

char str[5] = {'C','h','i','n','a'};

因此,用兩種不同方法初始化字元陣列後得到的陣列長度是不同的。

14.陣列名就是陣列的首地址,可以理解為指向陣列第一個元素的指標,但是,陣列名a不能像指標一樣做a++這個動作,原因是如果做了a++就丟失了陣列的首地址,系統將無法管理這段完整的記憶體空間了。

15.指標變數當做陣列名用:

int a[5];
int* p = a;
int i;
for(i = 0; i < 5; i++)
{
    p[i] = i + 1;
}

for (i = 0; i < 5; i++)
{
    printf("%d ", p[i]); // 相當於printf("%d ", *p); p++;
}

這段程式碼中,先讓指標p指向陣列a的首地址,之後把p當做陣列名來使用。你會發現沒有任何問題。

16.指向變數地址的指標:

int b = 5;

int* p = &b;

printf("%d ", *p);

這段程式碼很典型,很多教科書上都會用。b是一個變數,用指標p指向它。這段程式碼可以這樣理解:

  • 有一個int型的陣列a,這個陣列只有一個元素。int a[1];
  • b就是這個陣列中唯一的元素a[0]。a[0] = 5;
  • 指標p指向陣列a的首地址。int* p = a;相當於int* p = &a[0];也相當於int* p = &b;

17.指標初始化

int b = 5;
int* p;
p = &b;

相當於:

int b = 5;
int* p = &b;

指標之間賦值也是如此:

int* p = NULL;
int* p1;
p1 = p;

相當於:

int* p = NULL;
int* p1 = p; 

這兩種寫法完全相同,只不過是寫成一行後變成了簡寫形式。這種形式需要記下來,在指標作為函式形參傳遞時也同樣是這個原理。如下:

void fun(int* p)
{
    ...
}

int main()
{
    int b = 5;
    int* pp = &b;

    fun(&b);
    fun(pp);        
}

看懂了嗎,函式呼叫中形參的賦值相當於簡寫賦值形式。

18.指標訪問

基本形式是指標變數前加“*”。請看這段程式碼:

 int a[5] = {1, 2, 3, 4, 5};

 int* p = a;
 int i;

 for (i = 0; i < 5; i++)
 {
    printf("%d ", *(p + i));
 }

printf("\n");

 for (i = 0; i < 5; i++)
 {
    printf("%d ", *p++);
 }

第一個for迴圈採用的是偏移量計算的方式打印出每個元素。第二個for迴圈中採用移動指標的方式列印每個元素。不同之處在於,第一種方式指標位置不變化,第二中方法指標位置變化

19.指標的偏移

在我們對指標變數進行++或--的時候,實際上是記憶體地址的變化。那麼計算機怎麼知道一次變化多少呢?這取決於指標變數的型別

short a[5] = {1, 2, 3, 4, 5};

short* p = a;
long* pp = a;

p++; 
pp++;

printf("%d\n", *p);
printf("%d", *(short*)pp);

請自己執行這段程式碼,你會發現兩次列印的結果不同。因為p的型別是short,它做自加跳過一個short的大小,而pp做自加跳過一個long的大小,相當於兩個short大小。

20.puts() gets()

  • puts() 把一個字串列印到螢幕上
  • gets() 從鍵盤讀入一個字串

這兩個函式的定義在string.h中,使用時需要新增

#include<string.h>

puts()

  • 格式
    puts(字元陣列)

  • 功能
    向顯示器輸出字串(輸出完,自動換行,即用)

gets()

  • 格式
    gets(字元陣列)

  • 功能
    從鍵盤輸入一以回車結束的字串放入字元陣列中,並自動加"\0"

  • 說明
    輸入串長度應小於字元陣列維數,字串中可以包含空格

例如:

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

void main()
{
     char str[10];
     int i;
     printf("Please input a string:\n");
     gets(str);

     printf("The input string is:\n");
     puts(str);
}

同樣需要注意陣列長度的問題。

21.建立記憶體空間

int main()
{
    int* pBuf = (int*)malloc(10 * sizeof(int));


    free(pBuf);

    return0;
}

先做這兩步,開闢空間用指標pBuf管理,再用free釋放這段空間。在C語言中有一個malloc語句就一定要有一個free語句,這叫做程式碼的對稱性。否則將會出現記憶體洩露。切記這一點。

22.初始化空間

memset(pBuf, 0, 10 * sizeof(int));

這句話將這段記憶體全部用0填充。

相關推薦

C語言基礎知識總結

1.定義了變數一定要儘快賦一個值,我們叫初值。因為定義變數實際上是在記憶體中開闢了一塊新空間,但空間裡也許有之前留下的東西(資料)。所以,如果你不用初值把這塊空間覆蓋掉,很容易在後面出現莫名其妙的問題。

C++基礎知識和易混淆總結匯總(不定時更新)

以下是我本人不定時更新的易錯點彙總,如需轉載,請註明出處。 1、對指標的引用 int a = 10; int *p = &a; //初始化指標p。 int* &pa = p; //這個是對指標p的引用、在我們使用pa的操作。相當於對p的操作 2、函

淺談c語言中的

1、printf中字串過長時需要折行書寫使得程式更加易讀 printf("隨便打的話隨便打的話隨便打的話隨便打的話隨便打的話"); 用下面的方式直接折行會報錯 printf("隨便打的話隨便打的話隨便打的話 隨便打的話隨便打的話"); ①用””

C語言總結

       最近又把C語言看了一遍,發現了很多之前學C語言時沒有注意到但又很容易出錯的地方,現在總結出來和大家一起分享。可能有疏忽紕漏,歡迎大家指正。         一下分為幾個部分分別加以說明。 一、關鍵字 1.什麼是定義?什麼是宣告?兩者有何區別? 答:定義是建立一

C++ 筆試題總結(類和物件)

1、建構函式的意義:(1)由於類的部分成員是私有的,若程式需要對其進行初始化,只有通過成員函式實現。(2)在宣告物件時自動呼叫建構函式。2、建構函式沒有返回值,但不被宣告為void,即沒有宣告型別。3、每次建立類物件(甚至使用 new 動態分配記憶體時,C++都會使用建構函式

大話C#語言——基礎知識總結

推薦閱讀:  我的CSDN  我的部落格園  QQ群:704621321 時隔半年沒用C#了,最近打算回來鞏固一下,下面就著重一些主要的,易忘的,難點的知識點帶領大家一起回顧這個語言

c++陣列總結

c++陣列 1、只有在定義陣列是才能使用初始化,此後就不能使用了,也不能將一個數組賦給另一個數組 int cards[4] = { 3 , 6 , 8 , 10}; //ok int hands[4] ; /

C語言基礎知識總結

本文的目的是記錄平時工作學習過程中學習到的C語言知識,由於單獨一篇文章記錄的話可能篇幅過少,因此置頂此文用作此用處,本文從2017-12-16開始記錄,後續新增內容不單獨列出時間,在MarkEditor中有相應的版本記錄。 檔案描述符 EOF(end of

C/C++語言基礎知識總結

C或者C++內建的整數資料型別的長度是很含糊的。這種含糊性會導致難以預料的意外和後果,尤其是在不同CPU和不同編譯器之間移植嵌入式程式碼的時候。下面是內建的整數型別的基本規則:* char是8位的或者更長。基本的無限制的char可以預設為有符號的或者是無符號的;具體選擇哪種就

C++總結

返回值 oat 相對 變量 不堪 法規 內容 c++ 默認參數 在眾多編程語言中,C++語法規則是相對較為復雜的,其繼承和重載規則靈活多變,往往會讓初學這苦惱不堪,下面對於C++的一些易錯點進行的總結,希望有所幫助,本文章會持續更新。 函數重載與默認參數的二義性 在函

OO總結

space tor 初始化列表 audio 子類 book white hit 類的初始化 在寫子類的構造函數時,要在初始化列表中指定使用的父類的構造函數並完成其初始化,如下例: p,li { white-space: pre-wrap } AudioBook(co

C語言基礎知識整理

除法 當前 www 做到 初步 編寫 main函數 配對 十進制數 用一個簡單的c程序例子,介紹C語言基礎知識的基本構成、格式、以及良好的書寫風格,使小夥伴對c語言有個初步認識。 例1:計算兩個整數之和的c程序: #includemain(){int a,b,sum;

C語言基礎知識

sig 指向 開始 extern strong font 寬度 main bsp printf函數向終端輸出若幹個任意類型的數據。 表示輸出類型的格式字符     格式字符意義 a 浮點數、十六進制數字和p-計數法(C99) A

程序設計入門-C語言基礎知識-翁愷-期中測試

第一條 情況下 不出 等價 循環結構 true 語句 tdi ive 一、試題 程序設計入門—C 語言期中測評1 在代碼:while ( !e )中,!e 等價於:A.e ==0 B. e != 1 C. e!=0 D. e == 12. 以下代碼片段的輸出是:int j=

C語言基礎知識(一)結構體struct 和typedef struct區別

C與C++中struct 和typedef struct區別從三個方面對比 1、宣告變數方便: 在C語言中,常常見到typedef修飾結構體,如: #include<stdio.h> typedef struct _TEST { int value; char mat

C語言基礎知識(期末嘍)

演算法結構:一、順序結構、選擇結構、迴圈結構;二、迴圈結構又分為while型、until型、for迴圈結構;程式流程圖; 結構化程式設計方法:(1)自頂向下;(2)逐步細化;(3)模組化設計;(4)結構化編碼。 資料型別: 常量:常量包括字面常量、直接常量和符號常量; 變數:C語言規定標誌符只能由字母

C語言基礎知識——malloc

1、 malloc : 在堆上分配空間 void *mall (size_t size); 引數:要分配的空間大小,單位是位元組 返回值: 如果分配成功指向分配的空間 如果分配失敗,返回NULL free :釋放堆上的空間 void free(void *ptr); 引數:指向要釋放的空

C語言基礎知識——define、static、const

**1、**使用巨集函式的程式舉例: #include <stdio.h> #define PI 3.14 #define ADD(x, y) (x+y) #define MAX(x, y) ((x>y)?(x):(y)) int add(int x, int y)

C語言基礎知識——結構體

1、C語言中提供了一些由系統已經定義好的資料型別,如:int,float,char等,使用者可以在程式中用它們定義變數,解決一般的問題,但人們要處理的問題往往比較複雜,只有系統提供的型別還不能滿足應用的要求,C語言允許使用者根據需要自己建立一些資料型別,用它來定義變數。 2、C語言允許使

C語言基礎知識——函式2

1、通過return語句將函式值帶回到主調函式。 注:通常希望通過函式呼叫使主函式得到一個確定的值,這就是函式值(函式的返回值)。 如果函式不需要返回值,則不需要return語句。這時函式的型別應定義為void型別。 注:實參和形參在記憶體中佔不同夫人儲存單元,實參無法得到形參的值。 在定義