程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 指針引入,鼠標指針

指針引入,鼠標指針

編輯:關於C語言

指針引入,鼠標指針


指針:

一、聲明 一個 int 類型的 指針 然後 賦值。

 

二、聲明中直接賦值。 

 

三、空指針 

 

四、懸空指針 野指針:

 

懸空指針本質上就是 聲明了一個 指針類型的變量【如:int *p】,並且沒有賦值。在沒有賦初值的情況下,利用這個指針進行修改【如:*p=100】。就相當於這個指針指向了一個未知的地址。並且還做了修改。那如果這個地址是其他進程。還做了修改,就會造成系統的不穩定。因為這種不可靠的修改行為極其可怕,就好像呂伯奢開放了自己家給曹操,曹操進來以後胡亂的修改呂伯奢家人的數據,把是否存活全都置成了false.在dos版本的操作系統下,這種修改行為還是可以的。但是隨著後來越來越多的黑客想要修改操作系統的數據,就相當於我操作系統很大度,開放了我自己給你,你運行了一些東西,讓我這個操作系統土崩瓦解了。所以後來的操作系統做成了如下圖的樣子:

 

也就是隨著後來越來越多的這種可怕行徑,導致後來的法律發現如果你越界訪問的話,我們就認定你是非法入室罪名。就是有一個進程不斷地檢測,如果 有用戶進程非法訪問,就立刻把這個進程從內存中清楚,以保護操作系統的穩定。所以我們現在 是可以放心做這種懸空指針的案例演示的,不過就是 我們的進程遇到了問題,被迫中止而已。這是可以接受的。

五、指針的兼容問題

以下代碼:

#include <iostream>


void function1(void);
void function2(void);
void function3(void);
void function4(void);
void function5(void);
int main() {
    
    function5();
    
    return 0;
}

/**
    聲明 一個 int 類型的 指針 然後 賦值。 
*/
void function1(void){
    int i= 10;
    printf("修改前i的值為:%d\n",i);
    int *p;//定義一個 執行int 類型的指針 變量名為p.
    p = &i;//取i的地址 賦給 p。
    *p = 100;//*p表示:訪問p中的內容,根據int 這個類型,來提取這個元素。
    //又因為剛剛給這個裡面賦了i這個值 ,所以*p 相當於i。那麼i=100.
    //所以 *p = 100 本質上是一個賦值語句,將i的值改成了100.
    printf("修改後i的值為:%d\n",i);
}
/**
    聲明中直接賦值。 
*/ 
void function2(void){
    int i =10;
    int *p = &i;
    printf("i的值為:%d\n",*p);
} 
/**
    空指針 
*/
void function3(void){
    
    //int b = NULL;
    //printf("b的值為:%d\n",b);
    int *p = NULL;//這就是傳說中的空指針,在java中報了錯比較常見這個東西的,
    //就是因為在創建對象的時候,沒有給定一個初值,導致 報了那樣一個異常 
    printf("指針p的值為:%d,%p,%x",p,p,p);
}

/**
    懸空指針,野指針 :其實 跟function1()的內容有相像的地方,就是聲明一個指針類型的變量,但是不賦值。
    這個 編譯是可以通過的,但是運行的時候會報錯。在visual studio c++ 裡面編譯通不過。 
    這是因為。誰也不知道 到底讓p指向了一個什麼樣的內存單元。並且在不知情的情況下還給 它賦了100這個值,
    那這樣就會極其不安全。 
*/ 
void function4(void){
    int *p; 
    *p = 100;
    printf("懸空指針指向的地址的值是:%d\n",*p); 
} 

/**
    指針的兼容問題 
*/
void function5(void){
    //前面在第一個案例的時候有特意提到聲明了一個 int類型的指針變量,是因為除此之外還有各種類型的指針變量。
    //比如:
    char *pc;
    int array[10];
    int *p =array;//這個我現在有點兒蒙。。。 
    double *pd;
    //也就是我們說的,先去找到那個對應的元素然後按照 char 類型取pc裡面的內容 
    //按照double類型,取pd裡面的值
    //所以對於指針來說 他們的大小都一樣:
    printf("指針變量pc的大小:%d\n指針變量p的大小%d\n指針變量pd的大小%d\n",sizeof(pc),sizeof(p),sizeof(pd)); 
    //【查看運行結果圖】,會發現在這台機器裡面,所有的指針變量都是8,說明這是一個64位的操作系統。
    //如果這些數值都是4說明這是一個32位的操作系統。所以指針變量這個值的大小是操作系統相關的。 
    
    //所以,在取值的時候需要為這個被指向的對象指明一個類型,方便在取的時候,按照合理的類型把這個元素提取出來。 
    
    // 為了繼續進行先把這裡注釋掉,這裡很關鍵!一定要動手嘗試 
    //所以 如果是
    int *p1;
    char c;
    //p1=&c;
    //就會報一個這樣的錯誤: cannot convert 'char*' to 'int*' in assignment
    int *p2;
    unsigned int i1;
    //p1=&i1;
    //這個編譯還是很嚴格的,就是不行。在vs裡面這是被允許的。 
    //[Error] invalid conversion from 'unsigned int*' to 'int*' [-fpermissive]
    
    //但是 如果聲明一個 指向空類型的 指針 在進行指向是被允許的。
     
    void *pv;
    pv=&c;
    pv=&i1; 
    //這樣就是編譯通過的。 
    
    //p1 = pv;
    //[Error] invalid conversion from 'unsigned int*' to 'int*' [-fpermissive]    
}

 

上面是 main.cpp 的情況

 

下面是 main.c的情況:

 

#include <iostream>


int main() {
    int *p;
    unsigned int i;
    //p=&i; 
    //[Error] invalid conversion from 'unsigned int*' to 'int*' [-fpermissive]
    int ii;
    p=&ii;
    
    void *p1;
    p1 = p;
    
    char *pc;
    //pc = p1;
    //[Error] invalid conversion from 'void*' to 'char*' [-fpermissive]
    return 0;
}

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved