首頁>Club>
為什麼第一個for會出錯,而第二個for不錯 不是一樣的嗎?
8
回覆列表
  • 1 # OSDIY

    要理解指標必須先了解程式儲存原理,也就是程式碼和資料在記憶體中的組織情況。瞭解了這些後,指標其實就是記憶體地址而已。

    C對指標理解比較糾結一些,你也可以先去看看彙編,彙編可以理解為無型別,使用各種定址方式來實現資料存取。

    C中的指標操作也就這麼幾種,比如強制型別轉換,可以簡單的理解為立即數的賦值,值的內容就是記憶體地址。再如指標的加減,始終記住加減的是該指標指向資料型別長度的多少倍,int16 * Dataptr =xxx; Dataptr++;這裡的加加相當於地址直接加2。還有一個要記住:指標的指標還是指標。

  • 2 # AngelWings165094691

    指標 等於地址!宣告任何一個變數 結構 編譯器都會為它分配一個地址!獲取編譯器分配的地址採用 &符號!那麼設定編譯器分配的地址 就是 先 & 後*。彙編內不存在 型別 只有指標和 對齊格式! 如 變數 int A 這不是指標 那麼 代表不能指標操作嗎 這是錯誤的 先&A 然後用指標型別去讀 如整數型 (int*)&A=66 而int*a 只是省略了 &的操作 讓寫程式碼 更簡潔而已 其實效果一樣!

  • 3 # 瓦萊裡瀏覽量了餓的

    第一個迴圈條件出錯,稍微改一下。

    再來就是注意一下,不確定要迴圈幾次的時候最好用while(第二個迴圈i變數沒被用到 )

  • 4 # 大資料小菜雞

    c語言不太瞭解,但是第一個函式和第二個函式方法簽名一致你確定沒問題? 方法簽名指的是函式名和引數列表

  • 5 # EXCEL進階課堂

    你的問題指向是的C語言指標問題。看了你的配圖,發現你的問題不在指標身上,而在於你對於迴圈結構還沒有徹底把握。

    1.題主程式功能分析

    透過題主發的配圖來看,程式的功能是用兩種控制指標的方法來輸出指向陣列的元素值。

    但是第一個迴圈出現問題,表現的形式應該是死迴圈。為什麼會這樣呢?

    2.錯誤原因分析

    關於迴圈結構有幾個基本術語:

    這第1個迴圈中,p<=q是迴圈測試條件,其中的p是迴圈控制變數,對於迴圈控制變數需要做三個事情(應用break這種情況下有迴圈處理方法)

    第一:賦初值,題主的程式當中已有。

    第二:寫入到測試條件當中,題主已經完成。

    第三:更新,題主的程式當中沒有,正是因為這個原因,迴圈出現問題,出現死迴圈。

    3.修改方法

    根據題主的意圖,我把第一個迴圈結構修改為:

    或者修改為:

    學習的過程中,請注意基本功的練習和掌握。

  • 6 # 程式設計老大叔

    怎麼深刻理解C語言中的指標?又如何能靈活運用指標?這是大多數C/C++初學者都十分迷茫的地方;

    理解指標

    首先,你需要掌握兩個運算子“*”和“&”;

    “&”運算子:取物件在記憶體中的地址

    “*”運算子:取記憶體中地址上的物件(值);

    大家一定要深刻的理解上面兩個運算子,然後才能去進一步理解指標;

    int a = 100 ;這一行程式碼我想大家都沒問題。那麼“&a”返回的就是物件(變數)a在記憶體中的地址,它是一個16進位制數。

    然後用“*”號去a的地址去取物件:“*(&a)”,,就能取到物件a,也就就是100 ;

    接下來進入重點了,指標,本身也是一個變數(物件),它本身佔用記憶體,但是它只存地址(別人的地址),它存的誰的地址我們就稱它為指向誰的指標;

    int* p = &a ;int* p_2 = new int(200) ;先不管他的型別申明,只看變數本身p和p_2。前面講到指標存放的是物件的地址,那麼可以理解為指標是一個地址變數,那麼賦值的話就需要也賦一個地址給它一個地址。int* 和char*都可以表示地址型別,它們的區別就是地址所存的值得型別不同,一個是存整型,一個是存字元型;

    對指標取值的話,就是用“*”號,後面接物件地址,也就是指標變數,所以*p和*p_2就分別是a和200;

    指標的運用

    指標並不是C/C++獨有的,像C#和java等其實也是有指標的,只不過都被語言本身用其他的方式替代和封裝了一般程式設計師接觸不到,C/C++就不一樣,它是直接將指標暴露給開發者,因為大部分牽涉到指標的都與記憶體有關,而計算機記憶體很重要,萬一出什麼問題可能系統都會崩潰,下面就簡單來看一下程式在執行時指標與記憶體之間到底是個什麼樣的關係:

    先看一段程式碼:

    #include <stdio.h>

    #include <string>

    #include <iostream>

    #include <time.h>

    using namespace std;

    class people

    {

    public:

    people();

    ~people();

    string Name ;

    int age ;

    bool sex ;

    char info[1024] ;

    void run(){}

    void eat(){}

    private:

    };

    people::people()

    {

    }

    people::~people()

    {

    }

    int main()

    {

    people* p1 = new people();

    cout<<p1<<endl;

    cout<<&p1<<endl;

    cout<<sizeof(p1)<<endl;

    cout<<sizeof(*p1)<<endl;

    system("pause");

    return 0 ;

    }

    直接執行看結果:

    分析

    接下來來一一進行分析:

    首先people* p1 = new people();這一句是類的一個例項化,系統會給people例項化一個物件*p並且給它在堆上開闢空間,注意是在堆上,開闢的空間用來儲存物件的資料。資料包括哪些?就是物件的屬性和虛擬函式指標,但是函式並不儲存在各物件中。因此run()和eat()方法是不存在物件*p指向的記憶體處的。

    cout<<p1<<endl;輸出的是00279360,這是一個地址,是系統給new people()物件分配的地址。

    cout<<&p1<<endl;輸出的是0012FD90,這也是地址,但這是指標變數p本身的地址。

    cout<<sizeof(p1)<<endl;

    cout<<sizeof(*p1)<<endl;

    透過這兩個輸出就能有更清晰的認識了,p1本身只佔用4個位元組的空間,而它所指向的物件的地址所佔的空間就很大,等於類中所有資料型別所佔空間之和。

    接下來在main函數里寫一點邏輯:

    圖解

    我們來看一下程式執行時間,指標和記憶體是怎麼工作的。這裡畫一個圖給大家:

    程式在執行時,資料主要是儲存在棧、堆、程式碼區、全域性區。程式碼區主要就是存程式碼中出現的一些字元常量、方法等,比如這裡程式碼中給物件的Name屬性賦的值“xiaoli”之類的都是存在此處,然後我們透過new出來的物件,都是由堆透過計算好類中各屬性所需空間然後開闢出來的。這裡p3不是透過new開闢出來的,所以他是存在棧上的並且地址是固定的,是不能更改的,而p1和p2是能更改的。

    改變地址

    如此,我們三個物件互相賦值後會發生什麼呢?

    對比程式碼和輸出結果我們發現了什麼?賦值後p1和p2本身的地址並無改變,但是他所指向的記憶體都程式設計p3所在的記憶體了。下面用圖解給大家看一下:

    改變地址的值

    如果我將程式碼中的 p2 = &p3;換成*p2=p3呢?我們看下輸出結果:

    造成這種情況的原因,其實這就牽涉到指標的兩種賦值問題:一種是改變指向的地址,一種是改變本身指向地址的值p2 = &p3是改變指向地址,*p2=p3是改變指向地址的值。

  • 中秋節和大豐收的關聯?
  • 我到了孕晚期,晚上睡覺總難受,往哪邊側都難受,翻來覆去好長時間才睡著,會對寶寶有影響嗎?