從題目入門指針和動態一二維數組的歷程(萌新入門可參考)(上篇)

如果有問題求大佬指正…畢竟從百度學的
起因是做到c語言這本書5.13題是將兩個字符串不用strcat函數連接起來。
本來這是個簡單題目的,但收穫MAX!!!!!!!!
居然寫着寫着把指針和動態數組搞懂了一點,還把沒教的調用函數學了!
於是決定放出來讓大家一起來快樂學下嘿嘿嘿(如果以後沒聽懂某傑講的可以來康康我的這個鴨)[手動滑稽]
首先我們要寫入兩個字符串,以前都是規定長度比如str[100]什麼的,但如果輸入的字符串長度超過了100就會十分尷尬。如果str[100000000]那樣佔的內存又十分大,也不是很好。
於是就要採用動態數組的函數了,但指針沒學!!!
於是就找了個動態數組定義字符串的例子,然後根據裏面不懂的地方一個個百度去學習~~居然初步學懂了一點指針知識和調用函數的知識
例子在這裏https://blog.csdn.net/qq_38967295/article/details/84851606
但是他沒有任何一句解釋,對萌新十分不友好,我決定一句句百度出來。
代碼如下

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

int main()
{
    char *p = NULL;
    p = (char *)malloc(sizeof(char));
    scanf("%s", p);
    int len = strlen(p);
    char str[len];
    for (int i = 0; i < len; i++)
    {
        str[i] = *p;
        p++;
    }
    printf("%c\n", str[2]);

    free(p);
    p = NULL;

    system("pause");
    return 0;
}

首先#include裏多了沒見過的stdlib.h函數
百度一下
在這裏插入圖片描述
是相關指針的函數
其中還有
在這裏插入圖片描述NULL是空指針常量
這樣就不難理解代碼中第一行char *p = NULL;就是定義一個空的指針
emmm,話說char *p是什麼意思,百度一下(畢竟萌新沒學指針hhh)
在這裏插入圖片描述
也就是說,char *p是定義p爲字符串類型的指針,如果有指向的話應該是指向一個字符串地址中的首地址。而且從這裏也知道普通的定義一個字符串比如char p[]
是給p分配了內存的,但是char *p並沒有分配內存,按我的理解它就是一個記錄別的字符串首地址的參數。所以第一句到這裏已經很明瞭了,char *p = NULL就是定義p指針的值爲空,沒有任何指向,但接下來會指向字符串,因爲定義的是char。
好!下一句!
p = (char *)malloc(sizeof(char));
咳咳,至少sizeof看懂了,計算char的長度。
然後百度malloc用法
在這裏插入圖片描述所以前面的(char *)是類型轉換爲字符型指針,然後賦值給p,這裏懂了,後面就是開闢空間的意思吧?
繼續下一句。
scanf("%s", p);
這p不是指針嗎?爲何還能賦字符串進去呢?
百度一下
在這裏插入圖片描述原來如此,並不是賦字符串給指針,而是創建一個字符串,然後把字符串的第一個 字符地址送給指針!orz懂了懂了!
然後 scanf("%s", p);和gets( p );應該是一樣的,我就改成gets( p );好了
下一句 int len = strlen§; 計算p長度。等等,這是計算指針長度還是字符串長度呢?繼續百度~
在這裏插入圖片描述
還真的可以,sizeof是獲取指針長度, strlen是可以直接用指針獲取字符串長度!(容我這麼理解hhh)
繼續下一句 char str[len]; 這一句其實已經解決了我最開始的問題,這樣系統已經知道輸入是多少個字節了,就不怕多定義了。那接下來的語句是幹嘛用的呢?繼續看下去。

for (int i = 0; i < len; i++) { str[i] = *p; p++; }
一開始沒看懂(汗)然後百度發現
p前面加了*說明是這個地址中的值,也就是把這個地址中的值賦給了str[i]
而單單一個p則是代表指針,也就是地址。
那麼,這就是一個循環語句,用指針遍歷了一邊,把地址中的值賦給了str[i]。
明白了…之前所有東西都存在指針指向的那個地址中,但我們不知道在哪裏,所以要把那個地址中的字符串拿出來,到熟悉的str[i]方便運算。(雖然我覺得直接用指針運算也不是不行但可能那樣有點麻煩hhhh)
繼續!下面是 printf("%c\n", str[2]);
感覺沒有實際作用啊。。。我的理解就是把第三個拿出來看看是否實際賦值成功,也就是檢驗前面的操作是否正常。
在這裏插入圖片描述
嘿嘿沒錯說明前面思路對的並且是可實現的,自信心+1

    free(p);
    p = NULL;

接下來就很魔幻…我的理解就是出來混總是要還的,你向系統內存借了空間用完了當然要還給他並且清空。然後我試了試借了不還會發生什麼
結果發現刪除沒什麼影響。
問下度娘,沒弄到什麼,然後就寫自己的理解好了(不對見諒hhh)
如果不寫free()看來沒問題,但如果寫的代碼複雜一點估計很容易出事。
於是我就把free()和return 0;聯繫起來,return 0 不寫也可以運行,但大家都寫上,可能也是一種規範吧。

然後我又試了下只刪除free(p)和把free(p);p=NULL一起刪除,發現結果還是一模一樣正常運行
那爲什麼還要來寫個p=NULL呢,再問問度娘

在這裏插入圖片描述
get到野指針!原來free()釋放的只是內存空間,但指針還在的,要把它歸零。
要養成free()後加上指針歸零的習慣hhh
最後一句 system(“pause”);讓我很迷,這句真的不知道用來幹什麼…感覺沒必要啊???(如果後期有學到我會補充上去,但去掉這一句感覺更順暢的樣子…求解釋orz)

然後我就開始迴歸題目hhh,把這道不用strcat連接字符串的題目做了下。
然後想了下我要輸入兩個字符串,那麼要寫兩邊這個代碼,那麼麻煩!
於是就想能不能用調用函數的方法。

但是如果用調用函數會出現問題,因爲我只有一個str,運行兩遍的話str等於賦值兩次,會覆蓋掉,就沒辦法賦值到兩個數組裏連接在一起了。

於是

一開始想的解決方法是新建一個strA[]數組,加一個int i=0;i=i+1判斷一下是第一次輸入還是第二次輸入,然後如果第一次賦值給str後再賦值給strA[],如果是第二次就只用直接賦值給str就好了,不執行賦值strA[]的。實現是可以實現,但感覺我好傻。

於是!重點來了
動態二維數組是不是就可以了??
開闢新大陸,打開百度,動態二維數組,搜索!
!!!發現居然要用到指針的指針!woc可!!!我可以!!!
來肝!
下篇再繼續征程。
因爲二維指針可能又要來一個例子慢慢分析了,於是分爲兩篇博客,一上一下hhh
真的是個巨坑啊,一道課本基礎題居然可以無限挖到底,果然這是玄學!

PS:在學二維動態數組的時候忽然想到了一個致命點…我調用函數完了直接在函數外把函數返回值分別strcpy到str1和str2不就好了,用什麼二維數組啊…
傻了傻了傻了傻了

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