C++基礎與深度解析 | 數組 | vector | string

文章目錄

    • 一、數組
      • 1.一維數組
      • 2.多維數組
    • 二、vector
    • 三、string

一、數組

1.一維數組

??在C++中,數組用于存儲具有相同類型和特定大小的元素集合。數組在內存中是連續存儲的,并且支持通過索引快速訪問元素。

數組的聲明

??數組的聲明指定了元素的類型和數組的長度。

// 聲明一個整型數組,具有10個元素
int arr[10];// 聲明并初始化整型數組
int arr[] = {1, 2, 3, 4, 5};

注意:不要使用extern 指針來聲明數組,應該extern int array[];即Unknown Bounded Array 聲明

錯誤示例:

`file1.cpp`:
int array[3] = {1, 2, 3};`file2.cpp`://正確寫法
extern int array[];`file2.cpp`://錯誤寫法
extern int* array;

數組初始化

??數組的初始化可以是隱式的,也可以是顯式的。

  • 缺省初始化

    在C++中,如果數組是非靜態的局部數組,其元素將包含未定義的值,因為它們沒有默認初始化。全局數組和靜態數組將會被默認初始化為零。

    void function() {int localArray[10];  // 未定義的值static int staticArray[10];  // 初始化為0
    }
    
  • 聚合初始化( aggregate initialization )

    //使用大括號{}
    int arr[] = {1, 2, 3, 4, 5}; //根據初始化列表推導出int[5]
    

注意事項

  • 不能使用auto來聲明數組類型

    auto b = {1,2,3};	//b推導出的類型為std::initializer_list<int>int c[3] = {1,2,3};
    auto d = c;		//d推導出的類型為int*,類型退化了
    
  • C++中,數組(內置數組)不能直接復制。因為它們沒有像類或結構體那樣的拷貝構造函數或賦值運算符

    • 賦值操作:對于數組,你不能使用簡單的賦值操作(=)來復制數組。例如,以下代碼是錯誤的:

      int arr1[10] = {1, 2, 3};
      int arr2[10];
      arr2 = arr1; // 錯誤:數組之間不能使用賦值操作符
      
    • 拷貝構造函數:傳統數組沒有拷貝構造函數,這意味著你不能通過構造函數來創建一個數組的深拷貝

    盡管傳統數組不能直接通過賦值或拷貝構造函數來復制,你仍然可以通過其他方法來復制數組的內容。

    • 手動復制:使用循環手動逐個復制數組的每個元素

    • std::copy:使用C++標準庫中的 <algorithm> 頭文件提供的 std::copy 函數

    • 拷貝構造函數(對于數組類型的對象):如果你有一個包含數組的類或結構體,你可以定義一個拷貝構造函數來復制數組。

      struct MyStruct {int arr[10];MyStruct(const MyStruct& other) {std::copy(other.arr, other.arr + 10, arr);}
      };
      
    • C++11標準庫容器:如 std::arraystd::vector 提供了拷貝構造函數和賦值運算符來復制其內容。

      std::array<int, 10> arr1 = {{1, 2, 3}};
      std::array<int, 10> arr2 = arr1; // 使用std::array的拷貝構造函數std::vector<int> vec1 = {1, 2, 3};
      std::vector<int> vec2 = vec1; // 使用std::vector的拷貝構造函數
      
  • 元素個數必須是常量表達式(編譯期可計算的值)

  • 字符串數組的特殊性

    char str[] = "Hello";	//char[6]
    char str[] = {'H', 'e', 'l', 'l', 'o'}; //char[5]
    char str[] = {'H', 'e', 'l', 'l', 'o', '\0'}; //char[6]
    

    使用字符串字面量初始化字符數組

    char str[] = "Hello"; // char[6]
    

    在這行代碼中,"Hello" 是一個字符串字面量,它包含了字符串 "Hello" 以及一個隱式的空字符 \0,用作字符串的終止符。因此,當你使用這個字符串字面量來初始化字符數組 str 時,數組的大小是6個字符,包括5個可見字符和一個空字符。

    使用字符字面量初始化字符數組

    char str[] = {'H', 'e', 'l', 'l', 'o'}; // char[5]
    

    在這個例子中,使用花括號 {} 包圍的字符字面量列表來初始化字符數組 str。這種方式不會自動添加空字符 \0,因此初始化后的數組 str 將包含5個字符,即 'H', 'e', 'l', 'l', 和 'o'。數組的實際大小是5個字符。

    注意事項

    • 當使用字符串字面量初始化字符數組時,編譯器會自動在末尾添加一個空字符 \0,所以數組需要有足夠的空間來存儲這個額外的字符。
    • 當使用字符字面量列表初始化字符數組時,需要確保數組有足夠的空間來存儲所有字符,且不會自動添加空字符 \0。如果你需要一個以空字符終止的字符串,必須手動添加 \0
    • 字符串字面量和字符字面量列表在初始化字符數組時的行為不同,這可能會影響程序中字符串的處理和字符串函數的使用。

數組(數組到指針的隱式轉換)

??數組名在大多數表達式中會被解釋為指向數組首元素的指針。使用數組對象時,通常情況下會產生數組到指針的隱式轉換,隱式轉換會丟失一部分類型信息,可以通過聲明引用來避免隱式轉換

int arr[10];
int* ptr = arr;  // ptr是指向數組首元素的指針,數組到指針的隱式轉換auto& b = arr;	//聲明引用來避免隱式轉換

由于數組名可以作為指針使用,所以可以進行指針運算。

#include <iostream>int main()
{int arr[10];for (int* ptr = arr; ptr < arr + 10; ++ptr)  {// 操作數組元素*ptr = *ptr + 1;	//1}
}

指針數組與數組指針

  • 指針數組

    指針數組是一個包含多個指針的數組,每個指針可以指向不同的對象。

    語法:指針數組在聲明時,指針符號 * 放在數組名的前面。

    int* arr[3];
    
  • 數組指針

    數組指針是指向數組的指針。這種指針指向整個數組,而不是數組中的單個元素。

    語法:數組指針在聲明時,指針符號 * 放在數組類型后面,使用括號括起來

    // 創建一個整型數組
    int arr[] = {10, 20, 30};// 創建一個指向數組的指針
    int (*ptrToArr)[3] = &arr;
    

    ptrToArr 是一個指向數組的指針,它指向一個包含3個 int 的數組。ptrToArr 不是一個指向 int 的指針,而是指向整個數組。

注意

  • 當傳遞數組作為函數參數時,實際上傳遞的是指向數組首元素的指針,而不是整個數組。
  • 數組的生命周期和存儲空間必須在數組指針使用期間保持有效。
  • 指針數組和數組指針在內存布局和訪問方式上有所不同,需要根據具體需求選擇合適的類型。

聲明數組的引用:(C++中沒有引用數組的概念)

??聲明數組的引用意味著創建一個引用,它指向整個數組。數組引用在函數參數傳遞、大型數據結構的傳遞等方面非常有用,因為它們允許函數直接操作傳入的數組,而不是數組的副本。

int (&arr)[5] = data; // 假設 'data' 是一個已定義的數組

數組作為函數參數時,由于數組不能直接拷貝,通常會退化為指針。為了避免這種情況,可以使用數組引用作為函數參數

void printArray(int (&arr)[5]) {for (int i = 0; i < 5; ++i) {std::cout << arr[i] << " ";}std::cout << std::endl;
}int data[5] = {1, 2, 3, 4, 5};
printArray(data);

printArray 函數接受一個數組的引用作為參數。這意味著函數可以直接訪問和修改數組 data 中的元素。如果想限制數組中的元素不能修改,則void printArray(const int (&arr)[5])

注意

  • 數組引用必須在聲明時被初始化。
  • 數組引用的大小(數組的長度)必須是已知的,因此它們不能指向未指定大小的數組。
  • 數組引用通常用于函數參數,以便安全地傳遞數組并避免數組退化為指針

數組的元素訪問

  • 數組對象是一個左值(如果作為右值使用,類型會發生隱式轉換:int[3] --> int*

    C++中左值與右值

    在C++中,表達式可以根據它們是否可以取得內存地址被分為兩類:l-value(左值)和r-value(右值)。

    • l-value:l-value是指具有內存地址的表達式,這個內存地址可以被讀取和寫入。l-value通常用在賦值表達式的左邊

      l-value的例子:

      • 變量:int a;
      • 數組元素:int arr[10]; arr[0];
      • 函數參數:當函數參數是一個引用類型時,它是一個l-value。
      • 位域:當位域是一個對象成員時。
    • r-value:r-value是指那些沒有內存地址或者有臨時內存地址的表達式,它們不能被賦值,因為它們的存在時間很短暫。r-value通常用在賦值表達式的右邊,比如字面量、臨時對象、表達式的結果等。

      以下是一些r-value的例子:

      • 字面量:10
      • 表達式:a + b
      • 函數返回值:除非函數返回一個引用,否則返回的是一個r-value。
      int b = 20; // b是一個l-value
      int c = a + b; // a + b是一個r-value
      
  • 數組訪問

    使用時數組名通常會轉換成相應的指針類型(指向數組首元素的指針),本質上:arr[index] = *(arr + index),實際上是利用指針運算來訪問數組元素

    int arr[5] = {1, 2, 3, 4, 5};
    int firstElement = arr[0];  // 獲取第一個元素,值為1
    int thirdElement = arr[2]; // 獲取第三個元素,值為3
    
  • 范圍檢查

    C++不提供自動的數組范圍檢查,所以訪問數組元素時應該確保索引不會超出數組的界限。

    int arr[5];
    for (int i = 0; i < 5; ++i) {// 安全的訪問 arr[i]
    }
    
  • 越界訪問

    如果嘗試訪問超出數組實際大小的索引,將導致未定義行為,這可能引發程序錯誤,如數組越界錯誤、野指針引用等

獲得指向數組開頭與結尾的指針 :

int a[3] = {1,2,3};獲得指向數組開頭的指針:a     &(a[0])  std::begin(a)  std::cbegin(a)
獲得指向數組結尾的下一個元素的指針:a+3   &(a[3])  std::end(a)    std::cend(a)std::begin(a)與std::end(a)獲得的類型為int*
std::cbegin(a)與std::cend(a)獲得的類型為const int*

指針算術運算

  • 增加、減少

    指向數組下一位置元素的指針

  • 比較

    如果參數比較運算的指針是指向一個數組中的兩個位置 ,是可以進行比較運算的;如果指向的是不同數組,不建議這樣做,可能產生未定義的行為

  • 求距離

    #include <iostream>int main()
    {int a[3] = {1, 2, 3};auto ptr = a;auto ptr2 = a +3;std::cout << ptr2 - ptr << std::endl;	//3std::cout << ptr - ptr2 << std::endl;	//-3
    }
    
  • 解引用

  • 指針索引

    指針索引使用方括號 [] 來指定偏移量,從而訪問指針指向的內存位置之后的某個位置。

數組的其他操作

  • 求元素個數

    以下三種方法都是對數組進行操作(獲取數組的定義),而不是指針

    • sizeof方法: C語言方式,有危險,不推薦
    • std::size方法(C++17及以后):推薦的方式
    • std::end() - std::begin()方法:在運行期進行指針運算,但其實數組信息在編譯器就可以看到,增加了運行期負擔,不推薦
    #include <iostream>int main()
    {int a[3];std::cout << sizeof(int) << std::endl;	//4std::cout << sizeof(a) << std::endl;	//12//sizeof()方法求元素個數std::cout << sizeof(a)/sizeof(int) << std::endl; //3//std::size()   C++17// std::cout << std::size(a) << std::endl;//end-beginstd::cout << std::end(a) - std::begin(a) << std::endl;    //3
    }
    
  • 元素遍歷

    • 基于元素個數
    • 基于?begin/?end
    • 基于range-based for循環:語法糖
    #include <iostream>int main()
    {int a[3] = {2, 3, 5};//基于元素個數--C++17size_t index = 0;while(index < std::size(a)){std::cout << a[index] << std::endl;index = index + 1;}//基于(c)begin/(c)endauto ptr = std::cbegin(a);while(ptr != std::cend(a)){std::cout << *ptr << std::endl;ptr = ptr + 1;}//基于`range-based ` for循環for (int x : a){std::cout << x << std::endl;}
    }
    

數組–C字符串

  • C 字符串本質上是字符數組
  • C 語言提供了額外的函數來支持 C 字符串相關的操作 : strlen, strcmp…,這些操作都需要’\0’,知道C字符串到哪里結束
    • strlen():統計長度直到找到’\0’

2.多維數組

??多維數組本質上是數組的數組。其內存布局仍是連續存儲。

int x[3][4];  //x是一個數組,包含3個元素,x的每個元素是一個int[4]數組。
x[0];	//類型是int(&)[4]

聲明多維數組

??多維數組的聲明涉及指定每個維度的大小。在C++中,通常使用方括號來聲明多維數組。

// 聲明一個3x3的二維整型數組
int multiArray[3][3];// 聲明一個5x10的二維整型數組
int anotherArray[5][10];

初始化多維數組

??初始化時,每個維度的元素應該用花括號 {} 包圍,維度之間的元素應該用逗號 , 分隔。

  • 缺省初始化

  • 聚合初始化

    一層大括號與多層大括號

//其余元素默認初始化為0
int x2[3][4] = {1, 2, 3, 4, 5, 6};//其余元素默認初始化為0
int x3[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};//其余元素默認初始化為0
int x3[3][4] = {{1, 2, 3, 4}, {5, 6, 7}};// 初始化一個3x3的二維數組
int multiArray[3][3] = {{1, 2, 3},{4, 5, 6},{7, 8, 9}
};// 使用缺省初始化
int defaultArray[3][3] = {};

多維數組只能省略最高位的維度如:int x[][3],但是不建議這么干

多維數組索引與遍歷

  • 使用多個中括號來索引,訪問多維數組元素

    int value = multiArray[1][2]; // 獲取第二行第三列的元素,值為6
    
  • 使用多重循環來遍歷多維數組

    #include <iostream>int main()
    {int multiArray[3][3] = {{1, 2, 3},{4, 5, 6},{7, 8, 9}};//基于`range-based` for循環for (auto& p : multiArray)   //auto& 非常重要{for (auto q : p){        std::cout << q << std::endl;}}
    }
    

    下面分析for (auto& p : multiArray)for (auto p : multiArray)的區別

    image-20240505002541618

    image-20240505002635403

指針與多維數組

??在C++中,多維數組的數組名可以被看作一個指向數組首元素的指針。可以使用指針運算來操作多維數組。

int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
int (*ptrToRow)[3] = arr; // ptrToRow是一個指向具有3個整數的數組的指針// 訪問第一行的第二個元素
int value = (*ptrToRow)[1]; // 等于 arr[0][1],值為2
  • 多維數組可以隱式轉換為指針,但只有最高維會進行轉換,其它維度的信息會被保留。

    image-20240505003740863

  • 使用類型別名來簡化多維數組指針的聲明

    #include <iostream>using A = int[4];
    int main()
    {int x[3][4];A* ptr = x;
    }
    
  • 使用指針來遍歷多維數組

    #include <iostream>int main()
    {int x2[3][4] = {};auto ptr = std::begin(x2);while(ptr != std::end(x2)){auto ptr2 = std::begin(*ptr);while(ptr2 != std::end(*ptr)){ptr2 = ptr2 + 1;}ptr = ptr + 1;}
    }

二、vector

??C++標準庫中的 std::vector 是一個序列容器,是 C++ 標準庫中定義的一個類模板。與內建數組相比,std::vector 提供了更多的功能,例如自動調整大小、范圍檢查和一些有用的成員函數(更側重易用性)。std::vector 可復制、可在運行期動態改變元素個數(內建數組不可以)。

構造與初始化

  • 缺省初始化

  • 聚合初始化

  • 其他初始化方式–構造函數

    std::vector<T,Allocator>::vector,根據參數調用不同的構造函數

std::vector<int> vec; // 默認構造
std::vector<int> vec(10, 1); // 10個整數初始化為1
std::vector<int> vec = {1, 2, 3}; // 列表初始化

其他方法

  • 獲取元素個數、判斷元素是否為空、容量

    #include <iostream>
    #include <vector>int main()
    {std::vector<int> x(3, 1);//獲取元素個數--3std::cout << x.size() <<std::endl;//判斷元素是否為空,空返回1,不空返回0std::cout << x.empty() <<std::endl;//容量--3std::cout << x.capacity() <<std::endl;}
    
  • 插入元素

    vec.push_back(4); // 在末尾添加一個元素
    vec.push_back({5, 6, 7}); // 從初始列表添加多個元素
    
  • 刪除元素

    vec.pop_back(); // 刪除最后一個元素
    vec.erase(vec.begin() + 1); // 刪除第二個元素
    
  • vector比較

    逐個比較兩個vector的元素,如果元素相同,則比較下一個元素;如果第一個元素不同,則由第一個元素的大小決定;

  • 清空

    vec.clear(); // 刪除所有元素,保留容量
    
  • 修改容器大小

    vec.resize(5); // 改變vec的大小為5,如果縮小則可能刪除元素
    vec.resize(7, 1); // 如果需要,用1填充額外的空間以改變大小為7
    
  • 元素操作

    vec.front(); // 返回第一個元素
    vec.back(); // 返回最后一個元素
    

vector 中元素的索引與遍歷

  • []at實現vector 中元素的索引

    std::vector<int> vec(10, 1); // 10個整數初始化為1
    int firstElement = vec[0]; // 獲取第一個元素
    vec[1] = 20; // 設置第二個元素的值//at方法
    vec.at(2) = 30;
    
  • ?begin / ?end 函數 V.S. ?begin / ?end 方法

    #include <iostream>
    #include <vector>int main()
    {std::vector<int> x1 = {1, 2, 3};//begin、end函數auto p = std::begin(x1);while(p != std::end(x1)){std::cout << *p << std::endl;p = p + 1;}//begin、end方法auto q = x1.begin();    //返回指向第一個元素的迭代器,迭代器解引用也可以獲取元素的值while(q != x1.end()){std::cout << *q << std::endl;q = q + 1;}//forfor (auto x : x1){std::cout << x << std::endl;}
    }
    

    vector中?begin / ?end 方法返回的是隨機訪問迭代器

    迭代器

    • 模擬指針行為

    • 包含多種類別,每種類別支持的操作不同

    • vector 對應隨機訪問迭代器

      • 解引用與下標訪問

      • 移動

      • 兩個迭代器相減求距離

      • 兩個迭代器比較

        這兩個迭代器必須指向相同的vector

vector相關的其他內容

  • 添加元素可能使迭代器失效

    image-20240505131607321

  • 多維 vector

    如:std::vector<std::vector<int>>

  • .-> 操作符

    #include <iostream>
    #include <vector>int main()
    {std::vector<int>  x = {1, 2, 3};std::vector<int>* ptr = &x;std::cout << x.size() << std::endl;		//3std::cout << ptr->size() << std::endl;  //3
    }
    
  • vector 內部定義的類型

    • size_type

      image-20240505132432117

    • iterator / const_iterator

      image-20240505132511431

注意事項

  • std::vector 會根據需要自動調整大小,但可能會引起性能開銷,因為它可能需要重新分配內存和復制元素。
  • 訪問 std::vector 中的元素時,要注意范圍檢查,避免越界訪問。
  • 與原始數組相比,std::vector 更安全且易于使用,但可能會占用更多的內存,并且訪問速度可能稍慢。

三、string

??std::string 是標準庫中的一個類模板實例化,它提供了一個可變長度的字符序列,用于內建字符串的代替品。與內建字符串相比,更側重于易用性。string可復制、可在運行期動態改變字符個數

TypeDefinition
std::stringstd::basic_string

參考:std::basic_string

構造與初始化

#include <string>std::string str; // 默認構造,創建一個空字符串
std::string str("Hello, World!"); // 直接初始化
std::string str(10, 'A'); // 初始化為10個字符'A'

string其他方法

  • 訪問元素

    char ch = str[0]; // 獲取第一個字符,與C風格字符串不同,這是安全的
    
  • 添加和修改字符串

    str += "追加的字符串"; // 追加字符串
    str.append("追加的字符串"); // 另一種追加方式
    str.insert(1, "插入的字符串"); // 在指定位置插入字符串
    str.replace(1, 2, "新字符串"); // 替換部分字符串
    str.erase(1, 4); // 刪除從索引1開始的4個字符
    str.back() = '!'; // 修改最后一個字符
    
  • 尺寸相關方法(size/length)

    #include <iostream>
    #include <vector>int main()
    {std::string str= "Hello World!";size_t size = str.size();size_t len = str.length(); // 獲取字符串長度std::cout << size << std::endl;std::cout << len << std::endl;str.resize(10); // 改變字符串長度為10std::cout << str.size() << std::endl;std::cout << str.length() << std::endl;
    }
    
  • 查找和比較

    size_t pos = str.find("sub"); // 查找子串"sub"的位置
    bool isEqual = str.compare("anotherString"); // 比較字符串
    
  • 子字符串

    std::string sub = str.substr(1, 4); // 獲取從索引1開始的4個字符的子字符串
    
  • 清空

    str.clear(); // 刪除所有字符,保留容量
    
  • 交換

    str.swap(anotherStr); // 交換兩個字符串的內容
    
  • 轉換為C字符串,返回一個指向’\0’結束字符數組的指針

    const char* cstr = str.c_str(); // 獲取C風格的字符數組
    

注意事項

  • std::string 是一個類模板的實例化,所以它不是像原始數組那樣的低級類型。
  • 字符串字面量(如 "Hello")是 const char 類型的數組,它們在C++中被定義為 const,因此不能被修改。
  • 當需要C風格的字符串時,可以使用 c_str() 成員函數來獲取,但要注意,這個操作可能涉及內存分配,因此不應該頻繁調用。
  • std::string 提供了范圍檢查的訪問方式,避免了數組越界的問題

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11637.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11637.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11637.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端人員如何理解進程和線程

進程和線程的概念&#xff1a; 進程和線程本質都是cpu工作過程的時間片。 進程可以理解為cpu在運行指令即加載保存上下文所要用的時間。也可以理解為一個應用程序運行的實例。 線程是進程中更小的單位&#xff0c;描述一段指令所需要的時間。 進程是資源分配的最小單位&#xf…

【數據結構】數組循環隊列的實現

隊列&#xff08;Queue&#xff09;是一種特殊的線性數據結構&#xff0c;它遵循FIFO&#xff08;First In First Out&#xff0c;先入先出&#xff09;的原則。隊列只允許在表的前端&#xff08;front&#xff09;進行刪除操作&#xff0c;而在表的后端&#xff08;rear&#…

MySQL中導出CSV格式數據 | Java處理CSV數據

1. 導出不帶表頭的CSV數據 SELECT dataid, recordfilename INTO OUTFILE /tmp/uk_callcenter_event3.csv FIELDS TERMINATED BY , LINES TERMINATED BY \n FROM table_name WHERE createtime > 2024-03-27 22:00:00 AND createtime < 2024-04-29 23:59:59 AND timehou…

使用selenium控制已經打開的瀏覽器,應該如何實現。

要使用Selenium控制一個已經打開的瀏覽器實例&#xff0c;你可以通過以下步驟實現&#xff0c;這里以Google Chrome瀏覽器為例&#xff1a; 步驟 1: 啟動Chrome瀏覽器并啟用遠程調試 首先&#xff0c;你需要以遠程調試模式啟動Chrome瀏覽器。這可以通過在命令行中使用特定參數來…

python下載及安裝

1、python下載地址&#xff1a; Python Releases for Windows | Python.orgThe official home of the Python Programming Languagehttps://www.python.org/downloads/windows/ 2、python安裝 &#xff08;1&#xff09; 直接點擊下載后的可執行文件.exe &#xff08;2&…

Spring Boot項目怎么集成Gitee登錄

一、背景 現在的越來越多的項目&#xff0c;需要集成第三方系統進行登錄。今天我們以Spring Boot項目集成Gitee為例&#xff0c;演示一下怎么使用Oauth2協議&#xff0c;集成第三方系統登錄。 不了解oauth2的&#xff0c;可以看我之前的文章。Ouath2是怎么實現在第三方應用認…

MySQL創建儲存過程函數

DDL CREATE TABLE student (id int(11) NOT NULL AUTO_INCREMENT COMMENT 學號,createDate datetime DEFAULT NULL COMMENT 創建時間,modifyDate datetime DEFAULT NULL COMMENT 修改時間,userName varchar(30) NOT NULL COMMENT 學生名稱,pwd varchar(36) DEFAULT NULL COMME…

代碼隨想錄算法訓練營第五十二天

今日效率低下&#xff0c;努力把題做完。做快一點&#xff01;&#xff01;&#xff01; 300.最長遞增子序列 class Solution { public:int lengthOfLIS(vector<int>& nums) {if (nums.size() 1) return 1;vector<int>dp(nums.size(),1);int result 0;for(i…

計算機畢業設計Python+Spark知識圖譜課程推薦系統 課程預測系統 課程大數據 課程數據分析 課程大屏 mooc慕課推薦系統 大數據畢業設計

1 緒 論 1.1 課題研究背景 在線教育學習平臺是學生用來進行校內或校外拓展課程學習的平臺&#xff0c;平臺需要具備在線視頻觀看&#xff0c;作業提交&#xff0c;形成性考核等功能。在學生學習的過程中&#xff0c;學校的管理者或負責教師需要了解學生的學習情況和學習狀態&…

Spring STOMP-發送消息

如果你想要從應用程序的任何地方向連接的客戶端發送消息&#xff0c;要怎么做&#xff1f;任何應用程序組件都可以向brokerChannel發送消息。要這樣做&#xff0c;最簡單方法是注入一個SimpMessagingTemplate并使用它來發送消息。通常&#xff0c;你會按類型注入它&#xff0c;…

WWW服務器搭建(2)——Apache服務器配置與管理

一、Apache簡介 1.1 關于Apache Apache HTTP Server&#xff08;簡稱Apache&#xff09;是Apache軟件基金會的一個開放源碼的Web服務器&#xff0c;可以在大多數計算機操作系統中運行&#xff0c;由于其跨平臺和安全性被廣泛使用&#xff0c;是最流行的Web服務器端軟件之一。…

01-02-5

1、單鏈表中按位置查找 a.原理 通過傳遞的位置&#xff0c;返回該位置對應的地址&#xff0c;放到主函數定義的指針變量中。 我們認為位置從&#xff1a;有數據的節點開始計數 即如下結構&#xff1a; 查找位置&#xff0c;就是返回該位置對應的空間地址。 b.代碼說明 Ⅰ…

H5嵌入原生----兼容安卓與ios

主要分UI展示&#xff0c;鍵盤&#xff0c;輸入框等等。解決bug最苦惱的問題不是沒有解決方案&#xff0c;而是你沒有找到真正的原因。再就是現象難以重現&#xff0c;每次都要發布代碼&#xff0c;然后到手機app中去測試&#xff0c;模擬。這些地方會耗費大量的精力。 一、UI…

【軟設】常見易錯題匯總

目錄 計算機系統基礎 程序語言基礎 數據結構 算法設計與分析 計算機網絡與信息安全 軟件工程基礎 開發方法&#xff08;結構化與面向對象&#xff09; 數據庫 操作系統 知識產權相關的法律法規 &#x1f92f;&#x1f92f;&#x1f92f;&#x1f92f;&#x1f92f;&#x1f9…

《系統架構設計師教程(第2版)》第10章-軟件架構的演化和維護-07-軟件架構維護

文章目錄 1. 軟件架構知識管理1.1 概念1.2 架構知識的獲取1.3 作用1.4 架構知識管理的現狀 2 軟件架構修改管理3 軟件架構版本管理4. 示例4.1 背景4.2 數據獲取4.3 數據計算4.4 結果分析4.4.1 圈復雜度 (CCN)4.4.2 扇入扇出度 (FFC)4.4.3 模塊間耦合度 (CBO)4.4.4 模塊的響應 (…

mysql group by 細節介紹

mysql中group by的用法是配合聚合函數&#xff0c;利用分組信息進行統計&#xff0c;語句如“select name,sum(id) from test group by name,number”。 先來看下表1&#xff0c;表名為test&#xff1a; 執行如下SQL語句&#xff1a; SELECT name FROM test GROUP BY name 你…

OFDM802.11a的FPGA實現(十四)data域的設計優化,擠掉axi協議傳輸中的氣泡

原文鏈接&#xff08;相關文章合集&#xff09;&#xff1a;OFDM 802.11a的xilinx FPGA實現 目錄 1.前言 2.data域的時序要求 3.Debug 1.前言 前面12篇文章詳細講述了&#xff0c;OFDM 802.11a發射部分data域的FPGA實現和驗證&#xff0c;今天對data域的設計做一個總結。在…

electron 多窗口 vuex/pinia 數據狀態同步簡易方案(利用 LocalStorage)

全局 stroe 添加 mutations 狀態同步方法 // 用于其他窗口同步 vuex 中的 DeviceTcpDataasyncDeviceTcpData(state: StateType, data: any) {state.deviceTcpData data},App.vue 里 onMounted(() > {console.log("App mounted");/*** vuex 多窗口 store 同步*//…

springboot306基于Java的民宿管理系統(源碼+包運行+配套LW+技術指導)

項目描述 臨近學期結束&#xff0c;開始畢業設計制作&#xff0c;你還在做java程序網絡編程&#xff0c;期末作業&#xff0c;老師的作業要求覺的困難嗎?不知道畢業設計該怎么辦?網頁功能的數量是否太多?沒有合適的類型或系統?等等。今天給大家介紹一篇基于Java的民宿管理…

python篇-cmd 執行pip命令失敗,但執行pyhon命令正常

當你在CMD中可以正常執行python命令&#xff0c;但執行pip命令失敗時&#xff0c;這通常意味著pip沒有被正確地添加到系統的環境變量中。這里有一些步驟來解決這個問題&#xff1a; 檢查環境變量&#xff1a; 打開系統的環境變量設置&#xff08;右擊“此電腦”>“屬性”>…