1. 程式人生 > >二維陣列 字串 指標

二維陣列 字串 指標

IOS學習第12天

二維陣列

  • 二維陣列在記憶體中的儲存

1.二維陣列在記憶體中也是”從高到低申請連續記憶體的”,一共有行 * 列 * sizeof(單個元素的資料型別)

2.第0行是在”低”位元組

  • 二維陣列的地址和行列計算

1.二維陣列的地址 == 二維陣列名 == 二維陣列的低地址 == 二維陣列中第0行的地址 == 二維陣列中第0行第0個元素地址
== 二維陣列第0行的低位元組地址

2.二維陣列的長度以及行列計算

長度:二維陣列的總位元組數 / 單個元素的位元組數

sizeof(二維陣列名) / sizeof(單個元素的位元組數)

行數:二維陣列的總位元組數 / 每一行的位元組數

sizeof(二維陣列名) / sizeof(二維陣列名[0])

列數:每一行的位元組數 / 單個元素的位元組數

sizeof(二維陣列名[0]) / sizeof(單個元素的位元組數)
  • 二維陣列與函式

1.當二維陣列作為函式的引數的時候,會丟失這個二維陣列的行數和列數

2.當而為駐足作為函式的引數的時候,行數可以省略,要保證實參二維陣列的列數必須要和形參二維陣列的列數相同

3.寫引數的時候,可以先寫行數和列數,最後再寫二維陣列,然後二維陣列的列數用引數的列數來決定

void fuZhi(int row,int col,int nums[][col])
{
    //函式體:給nums這個陣列中的每一個元素賦值
for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { //nums[i][j] nums[i][j] = i*j+10; } // printf("\n"); } }

字串

  • 原理

將字串資料的每1個字元儲存到字元資料中,並在後面追加1個’\0’來表示儲存完畢

  • 格式
1>最基本的方式:
    char name[10] = {'a','b','c','\0'};


    2
>最簡單的方式: char name[30] = {"abc"};//看成 字串 "abc" 是四個字元 分別是'a''b''c''\0' 字串可見長度:3 字串實際長度:4 陣列的長度: 30 一般來說 如果問 一個字串的長度是多少?那麼就是指的 實際長度 3>最常用的方式: char name[] = "abc"; "字串可以看成一個字元陣列 "abcd" "但是 字元陣列 不一定是字串 char name[4]; name[0] = 'a'; name[1] = 'b'; name[2] = 'c'; name[3] = 'd'; 一個小題: char name[20] = {'j','a','c','k'}; 可以看成字串 "jack" char name[20] = {'j','a','\0','k'}; 可以看成字串 "ja" char name[10]; name[0] = 'j'; name[1] = 'a'; name[2] = 'c'; name[3] = 'k'; 不能,因為k後面雖然後字元,但是不一定是'\0' char name[4] = {'j','a','c','k'};不能,末尾沒有'\0' char name[4] = {"jack"}; 不能,末尾的'\0'已經超出了陣列範圍 ``` * 使用字元陣列儲存字串注意的地方 1.如果沒有指定的長度,給陣列賦值一個字串的時候,那麼陣列的長度是字串的可見長度+1 2.如果指定的字元陣列的長度小於等於了字串的長度,這個時候就會有問題 3.C語言中一箇中文字元佔3個位元組 * 使用%s輸出儲存在字元陣列中的字元資料 使用%s格式控制符,就可以輸出儲存在字元陣列中的字串資料 原理:從給定的地址開始,1個位元組1個位元組的輸出,指導遇到'\0'為止 缺點: 1.如果你要列印的字串中間有'\0',那麼只會列印'\0'前面的部分 2.輸入的字串中間不能有空格,如果有空格,只能儲存"空格"之前的字串 * 字串長度的計算

int len = 0;
char str[] = “aasdladjkwe”

while(str[len] != ‘\0’)
{
len++;
}
printf(“字串的長度為”)


* 與字串相關的函式

| 函式名 | 引數 | 作用 |
| -- | -- | -- |
| puts() | const char * | 輸出字串 |
| gets() | char * | 控制檯獲取輸入的字串 |
|strlen() | const char * | 計算字串的可見長度 |
| strcmp() | const char *, const char * | 比較兩個字串的大小 |
| strcpy()| char *, const char *| 拷貝字串 |
| strcat() | char *, const char * | 連線兩個字元陣列 |

### 指標
* 指標變數的宣告

1.什麼叫指標變數
一個變數,用來儲存另外一個變數的地址

如果一個指標變數p 儲存了 另外一個變數num的地址
那麼我們稱 這個指標變數 指向了 num變數

儲存了誰的地址 就指向了誰

2.指標變數有啥用?
可以通過指標變數,間接 訪問/修改/獲取 它所指向的變數中資料

3.如何宣告一個指標變數?**
語法:資料型別 * 指標變數名
int * p1;定義了一個指標變數 變數名叫p1,說明這個p1變數 能存int型別變數的地址

4.不同型別的指標變數,儲存對應型別的變數的地址


* 指標變數的初始化

1.什麼叫指標變數
一個變數,用來儲存另外一個變數的地址

如果一個指標變數p 儲存了 另外一個變數num的地址
那麼我們稱 這個指標變數 指向了 num變數

儲存了誰的地址 就指向了誰

2.指標變數有啥用?
可以通過指標變數,間接 訪問/修改/獲取 它所指向的變數中資料

3.如何宣告一個指標變數?**
語法:資料型別 * 指標變數名
int * p1;定義了一個指標變數 變數名叫p1,說明這個p1變數 能存int型別變數的地址

4.不同型別的指標變數,儲存對應型別的變數的地址


* 指標變數的使用

1.如何 使用指標變數 操作它所指向的變數的資料

int num = 10;
int *p_num = &num;//這裡的*代表 p_num是一個指標變數

通過p_num指標間接操作指標指向的變數
*p_num; //這裡的*代表 解析地址 解析出來就是num變數
列印:printf("%d",*p_num);
賦值:*p_num = 200;

* 野指標

.什麼是野指標:
亂指的指標,指標變數中儲存的值 是一個垃圾值
int num;//垃圾值
int * p_num;//垃圾地址
這個指標就是野指標
定義一個指標 但是沒有給他賦初始值,那麼這個指標就是野指標

2.定義一個野指標
int *p_num;
*p_num = 50;//非法操作
野指標 如果隨便訪問 那麼會遇到 難以預料問題
“`
* NULL值

1.
    int num = 0;//定義一個變數 如果不知道初始值,給他賦值一個0

    int *p_num = NULL;//如果定義一個變數,不知道初始值是什麼,那麼我們會給他一個預設值 NULL
    *p_num = 50;//會 100%報錯
2.如果1個指標變數的值是NULL值.這個時候通過指標變數去訪問指向的變數的時候 100%報錯.(沒有意義)

結論: 只要是申明瞭一個指標 不知道初始值
    那麼 我們這麼幹 int *p_num = NULL;
    ```
* 多個指標指向同一個變數
  1. int num = 10;

    int* p1 = #
    int* p2 = p1;

    p1和p2指標都指向了num變數.

2.練習:
int num1 = 10;//num1 的地址 0x1101
int num2 = 20;//num2 的地址 0x1102
int * p_num1 = &num1;// p_num1 裡面的值 0x1101

p_num1 = &num2;//p_num1 裡面的值 0x1102

*p_num1 = 30;//num2 = 30;

printf("num1 = %d,num2= %d\n",num1,num2);
* 指標作為函式的引數

**指標作為函式的引數是地址傳遞,在函式內部,如果改變了地址中變數的值,那麼呼叫者中的變數值也會一樣改變**

**一個函式具有多個返回值**

1.這個函式返回值有2個 但是一個函式只有一個返回值
2.就會想到指標,在主調函式中定義兩個變數
3.把這兩個變數的地址 作為引數傳遞給函式
4.在函式內部求出最大值最小值之後,將它們分別賦值給 這兩個地址解析後的變數裡
5.那麼函式呼叫完之後,主函式中的變數的值也會跟著改變

“`