- 1.C++與C的差異
- 1.15 動態申請內存耗盡
- 1.20 const
- 1.21 判斷系統是多少位系統
- 1.33 virtual 是如何實現多態的?
- 1.34 面向對象三大特性
- 1.35 重載 ,重寫 ,重定義
- 1.36 一個空類的對象占的字節數
- 1.37 內聯函數是否參數檢查
- 1.38 析構函數與虛函數
- 1.40 c++模板編程的理解
- 1.41 函數模板與類模板
- 1.41 運算符重載
- 1.42 基類的析構函數為什么必須是虛函數?
- 1.43 c++的左值與右值
- 1.44 數組名是指針,指向數組中第一個元素
- 1.45 計算機字長與指針所占存儲空間的大小
- 1.46 構造函數
- 1.47 常見的排序方式
- 1.48 c/c++程序的內存分配
- 1.49
- 1.5 對於return 語句的理解
- 1.51 拷貝構造函數與return
- 1.52 操作符號的優先級
- 1.53 位運算
- 1.54 編寫算法統計輸入字符串中不同字符出現的頻率
- 1.60 設計模式
- 1.61
- 1.62 字符串逆序
- 1.63 統計一個輸入字符串中中不同字符出現的頻率
- 1.64 假設以數組sequ[m]存放循環隊列的元素,同時設變量rear和quelen分別指示循環隊列中的隊尾元素的位置和隊列中內含元素的個數,試給出判別次循環隊列中的堆滿條件,並寫出相應的入隊和出隊的算法;(這個是數據結果)
- 1.64 十六進制數轉十進制數
- 1.65 假設以數組Q[m]存放循環隊列中的元素,同時以rear和length分別指示環形隊列中的隊
- 1.66 遞歸求和以及求均值
- 1.66 已知head為單鏈表的表頭指針,鏈表中存儲的都是整型數據,實現下列運算的算法:(1) 求鏈表中的最大值(2)求鏈表中的結點個數(3)求所有整數的平均值
1.C++與C的差異
1.1 C與c++中的struct的差異
a. C++語言將struct當成類來處理的,所以C++的struct可以包含C++類的所有東西,例如構造函數,析構函數,友元等,C++的struct和C++類唯一不同就是 struct成員默認的是public, C++默認private。
b. 由於C++中的struct是抽象數據類型,所以可以繼承也可以實現多態,只是因為有了class 一般不用它。
c. C語言struct不是類,不可以有函數,也不能使用類的特征例如public等關鍵字 ,是一些變量的集合體,可以封裝數據卻不可以隱藏數據。
d. +C語言中:struct是用戶自定義數據類型(UDT);C++中struct是抽象數據類型(ADT),所以下面代碼:
struct HE a; //C語言 變量方式
HE a; //C++語言 變量
1.2 C++中class與struct的區別與聯系
a. 默認訪問權限不同,C++中的class成員的默認屬性是private ,而struct默認屬性是public。
b.struct 可以定義相應結構所需的成員函數以及成員變量以及函數,可以有private ,public屬性,protected 屬性。
d.使用場景:.1,從此后只使用 class 定義類(一般的); 2,struct 只用來表示變量的集合(一般的),代表一個結構體;
c。使用方式:C++ 中的類支持聲明和實現的分離,意義在於分兩個角度來看待類,一個是聲明的角度、一個是實現的角度: 1,在頭文件中聲明 1,類的使用方式; 2,在源文件中實現類; 1,類的實現細節;
1.3如何判斷一段程序是c++還是c編譯的?
#ifdef __cplusplus
cout<<"c++";
#else
cout<<"c";
#endif
1.4 c與c++ 不同之處
a. C是一種面向過程的語言。
b。c++是面向對象的程序語言。其具有封裝,繼承,多態等面向對象的特性。
1.5 指針與引用的區別
a. 指針是本身存儲的所指向的對象的地址,而引用只是引用對象的別名。通過sizeof可以獲取指針的存儲空間的大小,而sizeof引用的話獲取的引用對象的存儲空間的大小。
b.指針在初始化可為空,指針指向的對象可以改變,而引用則不能為空,必須和引用對象綁定,而且之后不能改變。
1.6 sizeof
int id(sizeof(unsigned long))
1.7 static 的作用域
某一個文件中定義的靜態的變量,則它的作用域是整個文件。與之相對的的是extern
在a.h的頭文件中定義了一個靜態的全局變量x,不同文件的函數fun1和fun3會為每個包含該頭文件的cpp都創建一個全局變量,但他們都是獨立的,只在該cpp文件共享該變量。所以一般定義static全局變量時,都把它放在原文件中而不是頭文件,從而避免多個源文件共享,就不會給其他模塊造成不必要的信息污染。
1.8 c++ 中值傳遞的三種方式
1.9 inline 函數
inline函數僅僅是一個對編譯器的建議,所以最后能否真正內聯,看編譯器的意思,它如果認為函數不復雜,能在調用點展開,就會真正內聯,並不是說聲明了內聯就會內聯,聲明內聯只是一個建議而已。
1.10 virtual與inline
1.11 Debug和Release的區別
Debug:調試版本,包括調試信息,所以其容量一般來說比Release大很多,並且不進行任何的優化(優化會使得調試信息復雜化,因為源代碼和生成的指令之間關系會更復雜),以便於程序員進行調試。
Debug模式下生成兩個文件:除了.exe或者.dll文件外,還有一個.pdb文件,該文件記錄了代碼中斷點等調試信息。
Release:發布版本,不對源代碼進行調試,編譯時對應用程序的速度進行優化,使得程序在代碼大小和運行速度上都是最優的(調試信息可以在單獨的PDB文件中生成)。
Release模式下生成一個文件.exe或.dll文件
1.12 assert
assert的作用是先計算表達式 expression ,如果其值為假(即為0),那么它先向stderr打印一條出錯信息,然后通過調用 abort 來終止程序運行。
用法總結與注意事項:
1)在函數開始處檢驗傳入參數的合法性
2)每個assert只檢驗一個條件,因為同時檢驗多個條件時,如果斷言失敗,無法直觀的判斷是哪個條件失敗
3)不能使用改變環境的語句,因為assert只在DEBUG個生效,如果這么做,會使用程序在真正運行時遇到問題,
4)assert和后面的語句應空一行,以形成邏輯和視覺上的一致感。
5)有的地方,assert不能代替條件過濾。
assert是用來避免顯而易見的錯誤的,而不是處理異常的。一個非常簡單的使用assert的規律就是,在方法或者函數的最開始使用,如果在方法的中間使用則需要慎重考慮是否是應該的。方法的最開始還沒開始一個功能過程,在一個功能過程執行中出現的問題幾乎都是異常。
1.13 const 與#define
1.14 malloc/free 與 new delete
前者是c語言的庫函數,后者是c++運算符號
1.15 動態申請內存耗盡
1.20 const
const 放在函數后樣的函數叫常成員函數。常成員函數可以理解為是一個“只讀”函數,它既不能更改數據成員的值,也不能調用那些能引起數據成員值變化的成員函數,只能調用const成員函數。
修飾變量,說明該變量不可以被改變;
修飾指針,分為指向常量的指針和指針常量;
常量引用,經常用於形參類型,即避免了拷貝,又避免了函數對值的修改;
修飾成員函數,說明該成員函數內不能修改成員變量。
// 類
class A { private: const int a; // 常對象成員,只能在初始化列表賦值
public:
// 構造函數
// 類
class A
{
private:
const int a; // 常對象成員,只能在初始化列表賦值
public:
// 構造函數
A() : a(0) { };
A(int x) : a(x) { }; // 初始化列表
// const可用於對重載函數的區分
int getValue(); // 普通成員函數
int getValue() const; // 常成員函數,不得修改類中的任何數據成員的值
};
void function()
{
// 對象
A b; // 普通對象,可以調用全部成員函數、更新常成員變量
const A a; // 常對象,只能調用常成員函數
const A *p = &a; // 常指針
const A &q = a; // 常引用
// 指針
char greeting[] = "Hello";
char* p1 = greeting; // 指針變量,指向字符數組變量
const char* p2 = greeting; // 指針變量,指向字符數組常量
char* const p3 = greeting; // 常指針,指向字符數組變量
const char* const p4 = greeting; // 常指針,指向字符數組常量
}
// 函數
void function1(const int Var); // 傳遞過來的參數在函數內不可變
void function2(const char* Var); // 參數指針所指內容為常量
void function3(char* const Var); // 參數指針為常指針
void function4(const int& Var); // 引用參數在函數內為常量
// 函數返回值
const int function5(); // 返回一個常數
const int* function6(); // 返回一個指向常量的指針變量,使用:const int *p = function6();
int* const function7(); // 返回一個指向變量的常指針,使用:int* const p = function7();
1.21 判斷系統是多少位系統
定義一個指針,並通過sizeof計算指針占的字節數
#define OS_BITS (((int)((ptrdiff_t *)0 + 1)) << 3)
1.22
1.23
1.24 實參與形參
1.25 計算精度誤差
1.26 堆和棧
1.heap是堆,stack是棧。
2.stack的空間由操作系統自動分配和釋放,heap的空間是手動申請和釋放的,heap常用new關鍵字來分配。
3.stack空間有限,heap的空間是很大的自由區。
1.27 explicit與protected
explicit關鍵字只需用於類內的單參數構造函數前面。由於無參數的構造函數和多參數的構造函數總是顯示調用,這種情況在構造函數前加explicit無意義。 google的c++規范中提到explicit的優點是可以避免不合時宜的類型變換,缺點無。所以google約定所有單參數的構造函數都必須是顯示的,只有極少數情況下拷貝構造函數可以不聲明稱explicit。例如作為其他類的透明包裝器的類。 effective c++中說:被聲明為explicit的構造函數通常比其non-explicit兄弟更受歡迎。因為它們禁止編譯器執行非預期(往往也不被期望)的類型轉換。除非我有一個好理由允許構造函數被用於隱式類型轉換,否則我會把它聲明為explicit,鼓勵大家遵循相同的政策
1.28 淺拷貝與內存泄漏 ,深拷貝
1.30 數組名作為參數與int 作為參數的區別
1.31 程序的可讀性與可維護性-變量
1.32 const 的用法
1.33 virtual 是如何實現多態的?
1.34 面向對象三大特性
1.35 重載 ,重寫 ,重定義
1.36 一個空類的對象占的字節數
1.37 內聯函數是否參數檢查
1.38 析構函數與虛函數
析構函數是特殊的類函數,沒有返回類型,沒有參數,不能隨意調用,也沒有重載。在類對象生命期結束的時候,由系統自動調用釋放在構造函數中分配的資源。這種在運行時,能依據其類型確認調用那個函數的能力稱為多態性,或稱遲后聯編。另: 析構函數一般在對象撤消前做收尾工作,比如回收內存等工作
)在基類用virtual聲明成員函數為虛函數,這樣便可以在派生類中重新定義該函數,
2)在派生類中重新定義此函數,要求函數名、函數類型、函數參數個數和類型全部與基類的虛函數相同,並根據派生類的需要重新定義函數體;
3)定義一個指向基類對象的指針變量,並使得它指向同一類中需要調用函數的對象
4)通過該指針可調用此虛函數,此時調用的就是指針變量指向的對象同名函數。通過虛函數與指向基類對象的指針變量的配合使用。就能方便調用同一類族種不同的類的同名函數,只要先用基類指針指向即可。
1.40 c++模板編程的理解
1.41 函數模板與類模板
1.41 運算符重載
1.42 基類的析構函數為什么必須是虛函數?
1.43 c++的左值與右值
左值:用的是對象的身份
右值:用的是對象的值(內存)
decltype:當其作用於表達式時,如果求值結果是左值,那么返回一個引用
如果求值結果是右值,那么返回正常
int*p =new int(3);
int m = 3;
int &q = m;
decltype(p) dclp; //解引用運算生成左值,所以結果是int&
decltype(&q) dclq; //取地址生成右值
左值必須為常量
1.44 數組名是指針,指向數組中第一個元素
//一般ADarray是數組名,也就是數組首地址,i是偏移量,所以上面這個表達式也就是數組第i個元素的值
unsigned short array[] = { 1,2,3,4,5,6,7 };
int i = 3;
cout << *(array + i);
1.45 計算機字長與指針所占存儲空間的大小
機器字長是指計算機進行一次整數運算所能處理的二進制數據的位數(整數運算即定點整數運算)。因為計算機中數的表示有定點數和浮點數之分,定點數又有定點整數和定點小數之分,這里所說的整數運算即定點整數運算。機器字長也就是運算器進行定點數運算的字長,通常也是CPU內部數據通路的寬度。
1.46 構造函數
1.47 常見的排序方式
1.48 c/c++程序的內存分配
一、一個C/C++編譯的程序占用內存分為以下幾個部分:
棧區(stack):由編譯器自動分配與釋放,存放為運行時函數分配的局部變量、函數參數、返回數據、返回地址等。其操作類似於數據結構中的棧。
堆區(heap):一般由程序員自動分配,如果程序員沒有釋放,程序結束時可能有OS回收。其分配類似於鏈表。
全局區(靜態區static):存放全局變量、靜態數據、常量。程序結束后由系統釋放。全局區分為已初始化全局區(data)和未初始化全局區(bss)。
常量區(文字常量區):存放常量字符串,程序結束后有系統釋放。
代碼區:存放函數體(類成員函數和全局區)的二進制代碼。
1.49
a++是先賦值后運算的。也就是說a++在這里a還是原來的數,++a就是后賦值的得出在1的基礎上加1結果為2
1.5 對於return 語句的理解
1.51 拷貝構造函數與return
1.52 操作符號的優先級
輸出操作符號的優先級別高於條件操作符號
1.53 位運算
1.54 編寫算法統計輸入字符串中不同字符出現的頻率
注意防錯
輸入變量字符串
輸出欸一個字符出現的頻率 指針數組
1.60 設計模式
1.61
1.62 字符串逆序
char a[50];
cout << "please input a string:";
cin >> a;
int k = 0;
k = strlen(a);
cout << "Reverse order: ";
for (; k >= 0; k--) {
cout << a[k];
}
cout << endl;
return 0;
1.63 統計一個輸入字符串中中不同字符出現的頻率
#include <vector>
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
map<char, int> m_Count;
string str;
cout << "請輸入字符串!!" << endl;
getline(cin, str);
//相當於字典
for (size_t i = 0; i < str.size(); ++i)
{
m_Count[str[i]]++;
}
map<char, int>::iterator iter;
for (iter = m_Count.begin(); iter != m_Count.end(); ++iter)
{
cout << iter->first << ":" << iter->second << endl;
}
return 0;
}
1.64 假設以數組sequ[m]存放循環隊列的元素,同時設變量rear和quelen分別指示循環隊列中的隊尾元素的位置和隊列中內含元素的個數,試給出判別次循環隊列中的堆滿條件,並寫出相應的入隊和出隊的算法;(這個是數據結果)
(rear+1)%m == (rear-quelen+m)%m
入隊算法
void EnQueue(ElemType sequ[], ElemType value)
{
if((rear+1)%m == (rear-quelen+m)%m)
{
printf("隊列滿!");
return;
}
rear = (rear+1)%m;
sequ[rear] = value;
quelen++;
}
出隊算法
void DeQueue(ElemType sequ[], ElemType *value)
{
if(quelen == 0)
{printf("隊列空!");
return;
}
*value = sequ[rear];
rear = (rear-1+m)%m;quelen--;
}
1.64 十六進制數轉十進制數
//編寫一個函數,函數接收一個字符串, 是由十六進制數組成的一組字符串,
//函數的功能是把接到的這組字符串轉換成十進制數字.並將十進制數字返回
#include <iostream>
using namespace std;
// 十六進制字符串的最大長度
#define MAX_HEX_STR_LEN 8
bool hexToDec(char shex[], int & idec)
{
size_t i = 0, len = 0;
int mid = 0;
len = strlen(shex);
if (len > MAX_HEX_STR_LEN) {
return false;
}
idec = 0;
for (i = 0; i < len; i++) {
mid = 0;
if (shex[i] >= '0' && shex[i] <= '9') {
mid = shex[i] - '0';
}
else if (shex[i] >= 'a' && shex[i] <= 'f') {
mid = shex[i] - 'a' + 10;
}
else if (shex[i] >= 'A' && shex[i] <= 'F') {
mid = shex[i] - 'A' + 10;
}
else {
return false;
}
// 移位表示變為2的n次方倍
mid <<= ((len - i - 1) << 2);
idec += mid;
}
return true;
}
1.65 假設以數組Q[m]存放循環隊列中的元素,同時以rear和length分別指示環形隊列中的隊
1.66 遞歸求和以及求均值
#include<iostream>
using namespace std;
int get_array_max(int arr[], int n)
{
if (n == 1) {
return arr[0];
}
else {
return arr[n - 1] > get_array_max(arr, n - 1) ? arr[n - 1] :
get_array_max(arr, n - 1);
}
}
int get_array_max(int arr[], int n) {
if (n == 1) {
return arr[0];
}
else {
return arr[n - 1] < get_array_max(arr, n - 1) ? arr[n - 1] :
get_array_max(arr, n - 1);
}
}
int get_array_sum(int arr[], int n, int step) {
if (step == n) {
return 0;
}
return arr[step] + get_array_sum(arr, n, step + 1);
}
int main()
{
int arr[4] = { 1,3,4,5 };
int max=get_array_max(arr, 4);
}
1.66 已知head為單鏈表的表頭指針,鏈表中存儲的都是整型數據,實現下列運算的算法:(1) 求鏈表中的最大值(2)求鏈表中的結點個數(3)求所有整數的平均值
#include<iostream>
#include<algorithm>
using namespace std;
class ListNode
{
public:
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
//f(n)=max(f(n-1),an)
int getMax(ListNode* head, int Max)
{
if (head == NULL)
{
return Max;
}
else
{
return max(getMax(head->next, Max), head->val);
}
}
//f(n)=f(n-1)+1
int getSize(ListNode* head)
{
if (head == NULL)
{
return 0;
}
else
{
return(getSize(head->next) + 1);
}
}
//f(n)=(f(n-1)*(n-1)+an)/n
float getAverage(ListNode* head,int n)
{
if (head == NULL)
return 0;
else
{
return (float)(getAverage(head->next,n-1) * (n - 1) + head->val) / n;
}
}
};