C 語言常用小點
C字符串
C 基礎(chǔ)-指針泣洞,函數(shù)處理器
C 文件操作
JNI 基礎(chǔ) C語言版
C++ 基礎(chǔ)知識點大綱
[C++ 基礎(chǔ)經(jīng)驗知識點]
C++ 基礎(chǔ)代碼模板和使用
C++ 基礎(chǔ)-定點模式
C++ 宏定義
C++ 指針區(qū)分
C++ 指針特別篇-指針轉(zhuǎn)換和智能指針
C++ 類的繼承和多繼承
C++ this 原理
C++淺拷貝和深拷貝的原理
C++ 函數(shù)
C++ 仿函數(shù)
C++ 友元函數(shù)理解
C++ STL
C++ 模板函數(shù)純虛函數(shù)和Java對比
C++ 函數(shù)運算符重載(二)化簡版
C++ 多線程
C++ 算法包和源碼簡析
C++ 存儲持續(xù)性站超,作用域和鏈接性
自動存儲买置,執(zhí)行完代碼內(nèi)存自動釋放辟狈,生命周期由程序控制瓶蚂。 生命周期短再方法等大括號內(nèi)(代碼塊內(nèi))
靜態(tài)存儲持續(xù)性: static定義糖埋,函數(shù)外部定義,整個程序結(jié)束生命周期結(jié)束
線程存儲持續(xù)性: thread_local
動態(tài)存儲持續(xù)性: new 分配 delete釋放窃这。 由人工控制瞳别。
代碼塊作用域
#include <iostream>
using namespace std;
int main()
{
int teledeli = 5;
{
int teledeli = 20;
int weight = 30;
cout << "teledeli:" << teledeli << endl;
cout << "weight:" << weight << endl;
}
cout << "teledeli out:" << teledeli << endl;
return 0;
}
結(jié)構(gòu)體和類類似,方法可以定義在結(jié)構(gòu)體中
#include <iostream>
using namespace std;
struct Stock
{
int a;
void show(const Stock &s)
{
cout << s.a << endl;
}
};
int main()
{
Stock s;
s.a = 100;
s.show(s);
return 0;
}
外部變量钦听,就是文件內(nèi)函數(shù)外面的變量
static 存儲在堆生命周期是整個程序
#include <iostream>
using namespace std;
int c = 30;
static int b = 20;
int main1()
{
{
static int a = 10;
cout << a << endl;
}
cout << b << endl;
cout << c << endl;
}
在多文件程序中洒试,可以在一個文件(且只能在一個文件)中定義一個外部變量。使用該變量的其他文件必須使用關(guān)鍵字extern聲明它
統(tǒng)計輸入字符的個數(shù)
#include <iostream>
using namespace std;
void strcount(const char *str);
const int ArSize = 10;
// int total = 0;
int main()
{
char input[ArSize];
char next;
cin.get(input, ArSize);
while (cin)
{
cin.get(next);
while (next != '\n')
{
cin.get(next);
}
strcount(input);
cin.get(input, ArSize);
}
return 0;
}
void strcount(const char *str)
{
int count = 0;
static int total = 0;
cout << "\"" << str << "\" contains ";
while (*str++)
{
count++;
}
total += count;
cout << "total: " << total << endl;
cout << "count: " << count << endl;
}
兩個文件中朴上,全局限定變量和static 內(nèi)部限定變量區(qū)別(鏈接性)
file1
#include <iostream>
using namespace std;
int tom = 3; // 全局外部變量
int disc = 30;
static int harry = 300; // 全局內(nèi)部變量
void remote_accessx();
int main()
{
cout << "tom = " << tom << " in &tom " << &tom << endl;
cout << " disc = " << disc << " in &disc " << &disc << endl;
cout << " harry = " << harry << " in &harry " << &harry << endl;
remote_accessx();
return 0;
}
file2
#include <iostream>
using namespace std;
extern int tom;
static int disc = 10;
int harry = 1000;
void remote_accessx()
{
cout << "tom = " << tom << " in &tom " << &tom << endl;
cout << " disc = " << disc << " in &disc " << &disc << endl;
cout << " harry = " << harry << " in &harry " << &harry << endl;
}
說明符和限定符
auto register static extern thread_local mutable
- cv-限定符
- const
- volatile:代碼沒有對內(nèi)存單元修改垒棋,它的值也可能發(fā)生變化
編譯器會有自己的優(yōu)化過程
- mutable
結(jié)構(gòu)(或者類)變量為const 其成員變量也可以修改。
struct data{
char name[10];
mutable int access;
}
如果痪宰,const data veep ; veep.name 不可以重新修改叼架,veep.access 卻可以修改
- const
const 修飾的變量,不會影響變量聲明周期衣撬。變量聲明周期不會改變乖订。const的外置變量限定在了當(dāng)前文件中。
比如:文件1:const int test = 10; 通過inclue 等 文件2: const int test = 30; 互不影響具练。extern const int test = 10乍构;后,升級為外部變量扛点,但是不能再給test進(jìn)行修改哥遮,可以extern const int test ;這個時候這個test == 10
函數(shù)和鏈接性
函數(shù)內(nèi)部是不能在此定義函數(shù)陵究。默認(rèn)函數(shù)的鏈接是外部的眠饮。
也可以用extern 聲明,證明在外部是有函數(shù)定義的铜邮。(所以可以省略)
用static 定義函數(shù)仪召,那么在其他文件中用 static 也可以定義同樣函數(shù)寨蹋,那么限定為文件內(nèi)部,外部看不見扔茅。
static 聲明函數(shù)是內(nèi)部已旧,只能在當(dāng)前文件查找,我們做一個實驗
file1
#include <iostream>
using namespace std;
static void remote_access();
void remote_access();
int main()
{
cout << "main access" << endl;
remote_access();
return 0;
}
void remote_access()
{
cout << "remote_access 1" << endl;
}
file2
#include <iostream>
using namespace std;
static void remote_access()
{
cout << "remote_access 2" << endl;
}
void remote_access();
不同平臺咖摹,不同編譯器對順序要求不同评姨。但是思想是一樣。
存儲方案和動態(tài)分配
- new/delete/malloc()
- float *p = new float[20]
extern float *p = new float[20] - int *p = new int(6);
int *pi = new int;
double *pd = new double(99.9);
int * ar = new int[4]{2,3,4,5}; - new/new [] /delete/delete []
char buffer1[20];
char buffer2[500];
Struct_custom *p2 = new (buffer1) Struct_custom;
int *p4 =new (buffer2)int[20];
new 負(fù)責(zé)在堆找到足夠滿足要求的內(nèi)存塊
#include <iostream>
using namespace std;
const int BUF = 512;
char buffer[BUF];
const int N = 5;
int main()
{
cout << "buffer[BUF] address at:" << &buffer << endl;
double *pd1, *pd2;
int i;
cout << "Calling new and palcement new\n";
pd1 = new double[N];
pd2 = new (buffer) double[N];
for (i = 0; i < N; i++)
{
pd2[i] = pd1[i] = 1000 + 2.0 * i;
}
cout << "Memory addresses:\n"
<< " heap:" << pd1 << " static:" << (void *)buffer << endl;
cout << "Memory content:\n";
for (i = 0; i < N; i++)
{
cout << pd1[i] << " at" << &pd1[i] << ";";
cout << pd2[i] << " at" << &pd2[i] << endl;
}
cout << "\n Calling new and palcement new a second time:\n";
double *pd3, *pd4;
pd3 = new double[N];
pd4 = new (buffer) double[N];
for (i = 0; i < N; i++)
{
pd4[i] = pd3[i] = 1000 + 4.0 * i;
}
cout << "Memory content:\n";
for (i = 0; i < N; i++)
{
cout << pd3[i] << " at" << &pd3[i] << ";";
cout << pd4[i] << " at" << &pd4[i] << endl;
}
cout << "\n Calling new and palcement new a third time:\n";
delete[] pd1;
pd1 = new double[N];
pd2 = new (buffer + N * sizeof(double))double[N];
for (i = 0; i < N; i++)
{
pd2[i] = pd1[i] = 1000 + 2.0 * i;
}
cout << "Memory content:\n";
for (i = 0; i < N; i++)
{
cout << pd1[i] << " at" << &pd1[i] << ";";
cout << pd2[i] << " at" << &pd2[i] << endl;
}
return 0;
}
打印后buffer 的存儲地址收地址萤晴,和new出來的地址是同一個塊是個靜態(tài)地址吐句,new double是動態(tài)的。
名稱空間
#include <iostream>
using namespace std;
double pail;
namespace David
{
double pail;
void fetch();
}
namespace Lucy
{
double pail;
void fetch();
}
int main()
{
pail = 10;
Lucy::pail = 20;
cout << David::pail << Lucy::pail << endl;
return 0;
}
- using namespace David;
- using David::pail;
- David::pail;
Namespace.h
#include <iostream>
#include <string>
namespace pers
{
struct Person
{
std::string fname;
std::string lname;
};
void getPerson(Person &rp);
void showPersion(const Person &rp);
}
namespace debts
{
using namespace pers;
struct Debt
{
Person name;
double amount;
};
void getDebts(Debt &rd);
void showDebt(const Debt &rd);
double sumDebts(Debt *ar, int n);
}
Namespace.cpp
#include <iostream>
#include "Namespace.h"
namespace pers
{
using std::cin;
using std::cout;
void getPerson(Person & rp)
{
cout << "Enter first name: ";
cin >> rp.fname;
cout << "Enter last name: ";
cin >> rp.lname;
}
void showPersion(const Person& rp)
{
cout << rp.lname << ", " << rp.fname;
}
}
namespace debts
{
void getDebts(Debt & rd)
{
getPerson(rd.name);
cout << "Enter debt: ";
cin >> rd.amount;
}
void showDebt(const Debt& rd)
{
showPersion(rd.name);
cout << " Debt is:$ " << rd.amount << std::endl;
}
double sumDebts(Debt * ar,int n)
{
int total = 0;
for (int i = 0; i < n; i++)
{
total += ar[i].amount;
showPersion(ar[i].name);
showDebt(ar[i]);
}
return total;
}
}
UseNamespace.cpp
#include <iostream>
#include "Namespace.h"
void other();
void another();
int main()
{
using debts::Debt;
Debt golf = {
"Banny", "Goatsniff", 120.0
};
showDebt(golf);
other();
another();
}
void another()
{
using pers::Person;
Person collector ={"Milo","Rightshift"};
showPersion(collector);
std::cout << std::endl;
}
void other()
{
using std::cout;
using std::endl;
using namespace debts;
Person dg = {"Doodles", "Glister"};
showPersion(dg);
Debt zipply[3];
int i;
for (i = 0; i < 3; i++)
{
getDebts(zipply[i]);
}
for (i = 0; i < 3; i++)
{
showDebt(zipply[i]);
}
cout << "total debt: $" << sumDebts(zipply, 3) << endl;
}