指標與引用(面試寶典筆記三)

來源:互聯網
上載者:User
指標與引用
1:指標和引用的差別
    (1)非空區別。即指標可以賦空值,但引用不能。
    (2)合法性區別。在使用引用之前不需要測試它的合法性,相反,指標則總是被測試,防止其為空白。
    (3)可修改區別。引用指向的對象在初始化時確定,以後不可改變; 指標可改變指向。
    (4)應用區別。使用指標:a.存在不指向任何對象的情況。b.不同時刻指向不同的對象。
                     使用引用:總是指向同一對象,並且不需要改變指向。
例題:
1:please check out which of the following statements are wrong?
#include <iostream>using namespace std;int main() {int iv;int iv2 = 1024;int iv3 = 399;int &reiv;int &reiv2 = iv;int &reiv3 = iv;int *pi;*pi = 5;pi = &iv3;const double di;const double maxWage = 10.0;const double minWage = 0.5;const double *pc = &maxWage;cout << pi;return 0;}

 Answer:
錯誤:7,11,13行。
7:引用必須在聲明時同時初始化。
11:pi沒有指向,不可以對其賦值。
13: 本地的const常量必須在第一次聲明時就初始化。

例題2:
這個程式有什麼問題?該如何修改? 

char *strA() {    char str[] = “Hello World”;    return str;}

Answer:
str[]數組是屬於函數strA()的局部變數,當調用完這個函數後,局部變數str被銷毀,所以返回的結果是不確定且不安全的。
要獲得正確的結果,可做如下修改:
a. 

const char* strA() {    char *str = “Hello World”;    //”Hello World”是字串常量,它位於靜態儲存區,在程式的生命期內是恒定不變的。    //str是一個指標變數,它指向這個字串常量的首地址。//指標變數str的值是可以改變的(可以改變指向),不能改變的是記憶體中儲存字串常量的記憶體單元的值。    return str;}

b.
 

const char* strA() {    static char str[] = “Hello World”;/*靜態局部變數的生存期雖然為整個來源程式,但是其範圍仍與自動變數相同,即只能在定義該變數的函數內使用該變數。退出該函數後,儘管該變數還繼續存在,但不能使用它。*/    return str;}

更多知識點可參考:
C++五大記憶體分區及區別
字串常量的生命期與儲存域的討論
靜態變數的生存期與範圍

例題3:  

What results after run the following code ?

 

#include <stdio.h> int main() {    int *ptr;    ptr = (int *)0x8000;    *ptr = 123;    return 0;}

Answer:
會導致執行階段錯誤。
這種做法給一個指標分配一個隨意的地址,相當危險(直接給未作聲明的地址賦值編譯器會報錯的)。

例題4:
下面程式的輸出結果時什嗎? 

#include <iostream>#include <cstdio>using namespace std; class A {public:    int _a;    A() {        _a = 1;             puts("調用A的建構函式");    }             void print() {        printf("%d\n", _a);    }}; class B : public A {public:    int _a;    B() {        puts("調用B的建構函式");        _a = 2;         }}; int main() {    B b;    b.print();    printf("%d\n", b._a);    return 0;}

A. 2 2        B. 1 1        C. 1 2        D. 2 1
 
Answer:
C
B中的_a把A中的_a覆蓋,建立B類的對象時,先調用A類的建構函式,再調用B類的建構函式。
所以建立對象b之後,A類的_a為1,B類中的_a為2。
若要實現b.print();輸出2,可以在B中重寫print函數實現。

例題5:
下面程式會在哪一行崩潰?
 

#include <stdio.h> struct S {    int i;    int *p;}; int main() {         S s;    int *p = &s.i;    p[0] = 4;    p[1] = 3;    s.p = p;    s.p[1] = 1;    s.p[0] = 2;    return 0;}

Answer:
 

struct S {    int i;    int *p;}; int main() {         S s;    int *p = &s.i;        //即p指向s.i(p的內容為&s.i) ;    p[0] = 4;             //即s.i = 4;    p[1] = 3;             //即s.p = 3;    s.p = p;             //即s.p存了p的值,即&s.i;    s.p[1] = 1;             //s.p[1]即 *(&s.i + 1),也就是s.p。於是s.p[1] = 1;即s.p = 1;                        //s.p指向一個未作聲明的地址0x00000001;    s.p[0] = 2;             //s.p[0] = 2;即對s.p指向的地址賦值,相當於*((int *)1) = 2;                        //此時對一個未作聲明的地址賦值,程式崩潰。    return 0;}

//註:若調換sp[1] = 1;和s.p[0] = 2;的順序,程式可正常運行。

 測試:win下vs2010

linux下eclipse運行:

例題6:(數組指標)。
解釋a的輸出結果。
int (*a)[10];
a++;
 
Answer:
編程測試如下。a是一個數組指標,指向一個大小為10的數組。

a++;表示a指標向後移動1 * sizeof(數組)的大小,即向後移動40個位元組。
 

#include <stdio.h> int main() {         int v[2][10];    int (*a)[10] = &v[0];    int (*tmp)[10] = a;    a++;    printf("%d\n", (int)a - (int)tmp);    return 0;}

例題7:
null 指標和迷途指標的區別?

代碼:

#include <iostream.h>int main(){     int *pInt = new int;     *pInt=10;     cout<<*pInt<<endl;     delete pInt;     pInt=0;// 若未賦0,則變成迷途指標     *pInt=20;    // oh no, this was deleled.      cout<<*pInt<<endl;      return 0;}

迷途指標也叫懸浮指標,失控指標,是對一個指標delete後---這樣會釋放它所指向的記憶體---並沒有把它設定為空白時產生的.

而後,如果你沒有賦值就試圖再次使用該指標,引起的結果是不可預料的.

當delete一個指標時,實際上僅是讓編譯器釋放記憶體,但指標本身依然存在。這時它就是一個迷途指標。

當使用以下語句時,可以把迷途指標改為空白指標:

MyPtr=0;

通常,如果在刪除一個指標後又把它刪除了一次,程式就會變得非常不穩定,任何情況都有可能發生。但是如果你只是刪除了一個null 指標,

則什麼事都不會發生,這樣做非常安全。

使用迷途指標或null 指標(如MyPtr=0)是非法的,而且有可能造成程式崩潰。如果指標是使用null 指標,儘管同樣是崩潰,但它同迷途指標造成的崩潰相比是一種可預料的崩潰。這樣調試起來會方便的多

例題8:
C++中有了malloc / free,為什麼還要new / delete ?
測試程式如下: 

#include <stdio.h>#include <stdlib.h>class A {public:    int a;    A() {        puts("調用建構函式!");    }    ~A() {        puts("調用解構函式!");         }};int main() {    puts("使用new申請空間");    A *a = new A();    delete a;    puts("使用delete釋放");    puts("");    puts("使用malloc申請空間");    A *b = (A *)malloc(sizeof(A));    free(b);    puts("使用free釋放");    return 0;}

運行一下上面的程式便知區別。

運行之後仍不解,可參看文字說明:

C++中有了malloc/free,為什麼還需要new/delete?

原創文章如轉載請註明:轉自¥忘%風 {http://www.cnblogs.com/slave_wc}

本文地址: 指標與引用(面試寶典筆記三)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.