Lecture 5 C語言指針與字符串2

博主不定期更新【保研/推免、C/C++、5G移動通信、Linux、生活隨筆】系列文章,喜歡的朋友【點贊+關注】支持一下吧!


Lecture 5 指針與字符串

1. 指針

1.1 指針應用場景

詳情見:指針的應用場景(交換變量的值;求最大最小值;有理數加法;除法函數)

  • 函數返回多個值,某些值就只能通過指針返回
    傳入的參數實際上是需要保存帶回的結果的變量
void swap(int *pa, int *pb)
{
	int t = *pa;
	*pa = *pb;
	*pb = t; 
}
  • 函數返回運算的狀態,結果通過指針返回
    常用的套路是讓函數返回特殊的不屬於有效範圍內的值來表示出錯:1和0(在文件操作會看到大量的例子);但是當任何數值都是有效的可能結果(例如做除法)時,就得分開返回了
  • 常見錯誤:定義了指針變量,還沒有指向任何變量,就開始使用指針

1.2 指針與const(適用於C99)

  • 指針(p)是const:
    表示一旦得到了某個變量的地址,不能再指向其他變量
int *const q = &i; //q是const
*q = 26; //OK       
q++; //Error
  • 所指(*p)是const
    表示不能通過這個指針去修改那個變量(並不能使得那個變量成爲const)
const int *p = &i;     
int const *p = &i; 
//以上兩種方式等價
*p = 26; //Error! (*p)是const   
i = 26; //OK    
p = &j; //OK
  • 轉換
    總是可以把一個非const的值轉換成const的
void f(const int* x);
int a=15;
f(&a); //OK
const int b=a;

f(&b); //OK
b=a+1; //Error!

當要傳遞的參數的類型比地址大的時候,這是常用的手段:既能用比較少的字節數傳遞值給參數,又能避免函數對外面的變量的修改

1.3 const數組

  • const int a[] = {1,2,3,4,5,6,}; //數組變量已經是const的指針了,這裏的const表明數組的每個單元都是const int;所以必須通過初始化進行賦值
  • 保護數組值
    因爲把數組傳入函數時傳遞的是地址,所以那個函數內部可以修改數組的值;爲了保護數組不被函數破壞,可以設置參數爲const
    int sum(const int a[], int length);

1.4 指針運算

  • 可以做加減,對指針加1的結果是指針值+sizeof(指針變量類型),移到下一個單元
  • 指針-指針的結果是單元數之差,並不是地址的數值差,而是地址數值差/sizeof(指針變量類型)
  • *p++ \Leftrightarrow *(p++)
    • 取出p所指的那個數據來,完事之後順便把p移到下一個位置去
    • *的優先級雖然高,但是沒有++高
    • 常用於數組類的連續空間操作
    • 在某些CPU上,這可以直接被翻譯成一條彙編指令
  • 指針比較
    • <, <=, ==, >, >=, !=都可以對指針做
    • 比較的是它們在內存中的地址
    • 數組中的單元的地址是線性遞增的
  • 0地址
    • 當然你的內存中有0地址,但是0地址通常是個不能隨便碰的地址
    • 所以你的指針不應該具有0值
    • 因此可以用0地址來表示特殊的事情:
      • 返回的指針是無效的
      • 指針沒有被真正初始化(先初始化爲0)
    • NULL是一個預定定義的符號,表示0地址,有的編譯器不願意你用0來表示0地址

1.5 指針的類型

  • 無論指向什麼類型,所有的指針的大小都是一樣的,因爲都是地址;
  • 指向不同類型的指針是不能直接相互賦值的;這是爲了避免用錯指針。
  • 指針的類型轉換
    • void*表示不知道指向什麼類型的指針
      • 計算時與char*相同(但不相通)
    • 指針也可以轉換類型
      • int *p = &i; void*q = (void*)p;
    • 這並沒有改變p所指的變量的類型,而是讓後人用不同的眼光通過p看它所指的變量
      • 我不再當你是int啦,我認爲你就是個void

1.6 用指針做什麼

  • 需要傳入較大的數據時用作參數(例如傳入數組(數組是特殊的指針))
  • 傳入數組後對數組做操作
  • 函數返回不止一個結果
    • 需要用函數來修改不止一個變量
  • 動態申請的內存

2. 動態分配內存

#include <stdlib.h>
malloc     
void* malloc(size_t size);
  • 向malloc申請的空間的大小是以字節爲單位的,返回的結果是void*,需要類型轉換爲自己需要的類型(int*) malloc(n*sizeof(int))
  • free() //牢牢記住 有malloc 就有free
    把申請得來的空間還給“系統”
    申請過的空間,最終都應該要還,只能還申請來的空間的首地址
  • 常見問題
    • 申請了沒free \Longrightarrow 長時間運行內存逐漸下降
      • 忘了
      • 找不到合適的free的時機
    • free過了再free
    • 地址變過了,直接去free

3. 字符串

3.1 putchar

  • int putchar(int c);
  • 向標準輸出寫一個字符
  • 返回寫了幾個字符,EOF(-1)表示寫失敗

3.2 getchar

  • int getchar(void);
  • 從標準輸入讀入一個字符
  • 返回類型是int是爲了返回EOF(-1)
  • 結束讀入:Windows: Ctrl+Z ;Unix:Ctrl+D

3.3 字符串數組

char a[][10]= {
	“Hello”,
	“World”
	“Nihao”
};

3.4 程序參數

int main(int argc, char const *argv[])
argv[0]是命令本身

3.5 string.h

  • strlen
    size_t strlen(const char *s);
    返回s的字符串長度(不包括結尾的0)
  • strcmp
    int strcmp(const char *s1, const char *s2);
    比較兩個字符串,返回 0:s1== s2 1:s1>s2 -1:s1<s2
    遇到不相同時,後面就不會再比較
    做括號內的判斷條件時,需寫作 strcmp(s1, s2) == 0
  • strcpy
    char *strcpy(char *restrict dst, const char *restrict src);
    • 把src的字符串拷貝到dst(restrict表明src和dst不重疊,C99)
    • 返回dst(爲了能鏈起代碼來)
      應用:複製一個字符串
      char *dst = (char*) malloc(strlen(src)+1);
      strcpy(dst, src);
  • strchr
    char *strchr(const char *s, int c); //從左往右找字符
    char *strrchr(const char *s, int c); //從右往左找字符
    找到則返回一個指針,該指針指向該字符的位置;返回NULL(0)表示沒有找到;
    字符串中找字符串
    char *strstr(const char *s1, const char *s2)
    char *strcasestr(const char *s1, const char *s2); //忽略大小寫

4. ACLLib的基本圖形函數(瞭解即可)

4.1 ACLLib簡介

  是一個基於Win32API的函數庫,提供了相對較爲簡單的方式來做Windows程序;實際提供了一個.c和兩個.h,可以再MSVC和Dec c++(MinGW)中使用;以GPL方式開源在github上。

4.2 Windows API

  (API:應用程序編程接口)從第一個32位的Windows開始就出現了,就叫做Win32API;它是一個純C的函數庫,就和C標準庫一樣,使你可以寫Windows應用程序。

4.3 ACLLib的基本繪圖函數

  • 創建圖形窗口
    initWindow();
    Windows中座標原點在左上角,x從左往右增長,y從上往下增長
  • 終端窗口
    如果需要用scanfprintf,則需要首先initConsole();
  • 啓動/結束繪圖
    void beginPaint();
    void endPaint();
    任何繪圖函數的調用必須在這一對函數調用之間
  • 顏色
    RGB(r, g, b)
    紅色→RGB(255, 0, 0)
  • 點/線/畫筆/面/刷子/文字

4.4 如何在Windows的命令行中編譯C語言程序?

在系統變量path前加上Dev c++\MinGW64\bin的安裝路徑
本機如下路徑:F:\Dev-Cpp\MinGW64\bin; (英文分號)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章