日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【C++深度剖析教程15】经典问题解析之关于string的疑问

發布時間:2023/12/10 c/c++ 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++深度剖析教程15】经典问题解析之关于string的疑问 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天來看一下在面試筆試中經常會出錯的地方。
我們先來看一個代碼:

#include <iostream> #include <string>using namespace std;int main() {string s = "12345";const char* p = s.c_str();cout << p << endl; s.append("abced"); cout << p << endl; return 0; }

看一下這個代碼,第一感覺是沒有什么問題的,指針p指向了S這個字符串,那么當執行 s.append(“abced”);這句話之后,字符串S會增加“abced”這借個字符,那么打印輸出的結果應該為:12345和12345abced。但是我們運行程序發現(糾錯:使用gcc 4.4.7版本編譯器),兩條打印語句都是12345.這是為什么呢?下面我們看圖詳細分析一下:

一開始只是字符串S指向0xFF112233這個內存空間,然后讓P指向這個空間,執行這句話后:s.append(“abced”);S這個字符串變成了0x12345abced,同時這個字符串所對應的地址空間卻變成了:0xFF445566,但是此時指針P依然指向之前的0xFF112233,里面的值是沒有變化的,為什么出現這種情況呢?

因為:string對象維護了一個指向數據的char*指針,這個指針在程序運行階段,有可能會發生突變。
所以那個P指針還是指向原來的0xFF112233這個地址,打印輸出的內容就還是12345了。

糾錯:

  • 針對上述的說明,有網友提出質疑,在vs2013上運行結果就是12345和12345abced。我也做了實驗,在vs2017上運行結果也是12345和12345abced。而在我的Linux中,使用gcc
    4.4.7版本編譯器,運行結果就是12345和12345。使用gcc 7.3.0 編譯器,就得到12345和12345abced 這個結果。很明顯,這與編譯器實現有關,比較新版本的編譯器可以得到正常的運行結果。
  • 很明顯,我一開始的分析,也是有一些錯誤的。string對象維護了一個指向數據的char* 指針,這個指針在程序的運行階段是有可能發生突變,也有可能不發生突變。比較新的編譯器編譯都沒有發生突變,說明比較新的編譯器解決了那個bug。
  • 在我下面的評論中,我之前說可以從另一個角度理解為什么打印結果一樣,就是const,這種說法也是不對的,const修飾的變量,則該變量不能出現在賦值符號的左邊,不能被直接改變,但是可以被間接改變。

下面再看一個程序:

#include <iostream> #include <string>using namespace std;int main() {const char* p = "12345";string s = "";s.reserve(10); //分配內存大小為10// 不要使用 C 語言中的方式操作 C++ 中的字符串for(int i=0; i<5; i++){s[i] = p[i];}cout << s << endl;return 0; }

這個程序運行結果為:空!!!
為什么呢?難道對S的賦值沒有成功么?我們給出分析,用C語言描述C++中的字符串,會出現一些異常,看圖:

這里可以看出,m_cstr是指向字符串的內容,m_length是string類的成員變量,它指向字符串的長度,經過for循環后,我們操作的不是對象的整體,m_cstr所指向的字符串確實有了,但是m_length卻依然為0,所以最后打印出來的是空,我們應該直接操作這個對象,才能讓m_length隨著賦值而改變。

我們把程序改成這樣:

#include <iostream> #include <string>using namespace std;int main() {const char* p = "12345";string s = "";s.reserve(10);s = p; //直接操作對象,不要像C語言那樣進行for循環賦值。// 不要使用 C 語言中的方式操作 C++ 中的字符串/*for(int i=0; i<5; i++){s[i] = p[i];}*/ cout << s << endl;return 0; }

打印結果為:

這下就是我們期待的結果了。

總結一下:
-string類通過一個數據空間保存字符串數據
-string類通過一個成員變量保存當前字符串的長度
-C++開發時,盡量避免C語言的一些慣用的編程思想

想一起探討以及獲得各種學習資源加我:
qq:1126137994
微信:liu1126137994
可以共同交流關于嵌入式,操作系統,C++語言,C語言,數據結構等技術問題。

總結

以上是生活随笔為你收集整理的【C++深度剖析教程15】经典问题解析之关于string的疑问的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。