C++ Primer Plus 6th代码阅读笔记
C++ Primer Plus 6th代码阅读笔记
-
第一章没什么代码
-
第二章代码
- carrots.cpp :
- cout 可以拼接输出,cin.get()接受输入
- convert.cpp
- 函数原型放在主函数前,int stonetolb(int); 1 stone = 14 pounds 一英石等于十四英镑
- cin.get( )会读取输入字符,包括回车
- ourfunc.cpp
- using namespace std会在作用域里其作用,所以写在函数内的话,函数外不起作用
- 两次cin >>count,正常运行,说明cin >>(int或char)接受非空格,函数重载
- 对比cin.get()接受空格
- 若先cin >>(int或char)再cin.get(),且输入为a和回车,回车会被cin.get()截得
- carrots.cpp :
-
第三章代码
- arith.cpp
- cout.setf(ios_base::fixed, ios_base::floatfield);
- 第一个参数:fmtflags:bool,decimal-integer,hexadecimal-integer,floating
- 第二个参数:scientific|fixed:floatfield
- 通常cout会删除结尾的零。例如,将3333333.250000显示为3333333.25。调用cout.setf( )将覆盖这种行为,至少在新的实现中是这样的。
- fixed:定点表示法
- floatfield:科学定点
- 如果cin >> hats; cin >> heads;cin.get(); == cin >> hats; cin.get(); cin >> heads;cin.get();
- assign.cpp
- 浮点数强制转为整数:直接去掉小数点后的
- \a表示振铃
- \b表示退格
- devide.cpp
- 浮点常量默认为double
- 1.e7是double,1.e7f是float
- 对于long double类型,可使用l或L后缀(由于l看起来像数字1,因此L是更好的选择)
- short int 2bytes -32768 to 32767
- int 4bytes -2147483648 to 2147483647
- float 4bytes:大概也是10位,小数点后6位,不太清楚
- double 8bytes,小数点后15位,不太清楚
- 可以直接用INT_MAX来查,sizeof (int),sizeof 变量名
- 所以int默认是有符号的int
- fltadd.cpp
- 程序将数字加1,然后减去原来的数字。结果应该为1,但是结果为0。问题在于,2.34E+22是一个小数点左边有23位的数字。加上1,就是在第23位加1。但float类型只能表示数字中的前6位或前7位,因此修改第23位对这个值不会有任何影响。
- hexoct1.cpp
- 0x42十六进制 042八进制
- cout默认以十进制输出
- hexoct1.cpp
- cout << hex;可以更改为十六进制输出
- modulus.cpp
- int/int,int%int
- morechar.cpp
- cout.put(’!’);
- typecast.cpp
- static_cast<>可用于将值从一种数值类型转换为另一种数值类型。
- 运算符static_cast<>比传统强制类型转换更严格
- 可能会更安全
- arith.cpp
-
第四章代码
-
addpntrs.cpp
- 数组头指针,直接数组名或者&数组名[0]
- stacks[1] 等价于 *(stacks + 1)
- sizeof(数组名) = 整个数组的大小,单位是字节,如果长度为10,int数组,10*4 = 40
- sizeof(pw) 指针的大小都是8个字节(对于64位系统),不管是double指针和int指针
-
arraynew.cpp
- double * p3 = new double [3]; // space for 3 doubles
- 定义指针指向开辟的内存
- delete [] p3;
-
arrsruct.cpp
-
结构体定义
-
定义完结构体,再定义结构体数组
-
结构体有点像int类型,是一种类型
-
结构体数组的定义及初始化
-
guests[0].volume来得到该…
-
代码
-
inflatable guests[2] = // initializing an array of structs {{"Bambi", 0.5, 21.99}, // first structure in array{"Godzilla", 2000, 565.99} // next structure in array };
-
-
choices.cpp
- double a1[4] = {1.2, 2.4, 3.6, 4.8};
- vector a2(4);
- a2[0] = 1.0/3.0;
- a2[1] = 1.0/5.0;
- a2[2] = 1.0/7.0;
- a2[3] = 1.0/9.0;
- array<double, 4> a3 = {3.14, 2.72, 1.62, 1.41};
- 索引-2是什么意思呢:找到a1指向的地方,向前移两个double元素,并将20.2存储到目的地。也就是说,将信息存储到数组的外面。与C语言一样,C++也不检查这种超界错误。这表明数组的行为是不安全的。
-
delete.cpp
- 三种存储方式:自动存储,静态存储,动态存储。
- 自动存储
- 它们在所属的函数被调用时自动产生,在该函数结束时消亡
- 实际上,自动变量是一个局部变量,其作用域为包含它的代码块。代码块是被包含在花括号中的一段代码。
- 自动变量通常存储在栈中
- 静态存储
- static double fee = 56.60
- 存在于程序的整个生命周期
- 动态存储
- new和delete运算符
- 自由存储空间(free store)或堆(heap)
- 程序员对程序如何使用内存有更大的控制权
- 自动添加和删除机制使得占用的内存总是连续的,但new和delete的相互影响可能导致占用的自由存储区不连续,这使得跟踪新分配内存的位置更困难。
- 如果使用new后不使用delete,会导致内存泄漏,该内存无法收回
- C++智能指针有助于自动完成这种任务
-
instr1/2/3.cpp
- 都是输入给char name[ArSize];而不是char * name;
- char name[Arsize];
- cin>>name;//不接受回车,空格,但是当输入“dec liu”时,会被看成两次输入
- cin使用空白(空格、制表符和换行符)来确定字符串的结束位置,这意味着cin在
获取字符数组输入时只读取一个单词。读取该单词后,cin将该字符串放到数组中,并自动在结尾添加空字符。 - cin.getline(name,Arsize);//接受回车,空格
- getline( )函数每次读取一行。它通过换行符来确定行尾,但不保存换行符。相反,
在存储字符串时,它用空字符来替换换行符,空字符即字符串末尾。 - 此时输入“dec liu”就正常
- cin.get(name, ArSize).get();
- get并不再读取并丢弃换行符,而是将其留在输入队列中
- get()可以知道读取停止是因为已经读取了整行还是由于数组已填满呢
- cin.getline()和cin.get()都有空行问题,读取到空行,会设置失效位,接着输入被阻断,但可以用cin.clear(),来继续输入。
- 总结:
- 第一种:怕长度长的,怕有空格的输入,会导致一次输入变成来两次输入
- 第二种:怕长度长的和直接回车的,都会设置失效位,读取会停止
- 第三种:可以可以知道读取停止是因为已经读取了整行还是由于数组已填满呢
-
mixtypes.cpp
- 结构体指针
- 结构体数组trio.trio是数组名,trio->year;数组名本质是地址,可以这样->,而不是.
- auto的作用:以后再看
-
newstrcut.cpp
- ps->name
- (*ps).volume
-
numstr.cpp
- 用户根本没有输入地址的机会。问题在于,当cin读取年份,将回车键生成的换行符留在了输入队列中。
-
ptrstr.cpp
-
cout<<字符串地址,输出字符串;可以接受char animal[20]的animal,const char * bird的bird
-
delete [] ps;
-
ps = animal;指向同地址
-
ps = new char[strlen(animal) + 1]; strcpy(ps,aniaml);
-
可以cout<< (int *) animal来看animal字符串的地址
-
如果直接char * ps;接着cin >> ps; 不行,因为ps的指针是未知的
-
内存必须先申请再读写
-
strtype1/2/3/4.cpp
- #include // C-style string library
- C风格:strcpy,strcat,strlen
- 未被初始化的数据,第一个空字符的出现位置是随机的,对于char charr[20];
- cin.getline(charr, 20); charr的输入
- getline(cin, str); str的输入
-
-
use_new.cpp
- double * pd = new double; *pd = 10000001.0;
- 地址在堆区,指针在栈区
-
-
第五章代码
-
bigstep.cpp
- 可以单独using std::cout;
-
comstr1.cpp
- for循环括号内,++的可以是char,判断条件可以是返回bool的函数,打破思维
-
dowhile.cpp
- 对于先输入再判断的,可以用do while
- 强行转换非0int转为bool是true,包括-1
-
express.cpp
- 通常,cout在显示bool值之前将它们转换为int,但cout.setf(ios::boolalpha)函数调用设置了一个标记,该标记命令cout显示true和false,而不是1和0。
- cout.setf(ios_base::boolalpha);
-
forstr2.cpp
- string word; cin >> word;
- 交换
- temp = a
- a = b
- b = temp
- for 循环里同时放两个变量,一个指前,一个指后
-
nested.cpp
- \t制表符
-
textin1/2/3/4.cpp
-
cin<<ch 不接受空字符,是个问题
-
可以在#后面输入字符,是个问题
-
使用cin.get(char)进行补救,可以解决不接受空字符的问题
-
cin.get(char)是通过引用来修改值的,不同于使用变量的地址
-
linux系统的ctrl + d才是EOF,ctrl + z是暂时挂起,按fg可恢复
-
Windows系统的ctrl + z是EOF
-
由于EOF表示的不是有效字符编码,因此可能不与char类型兼容。例如,在有些系统中,char类型是没有符号的,因此char变量不可能为EOF值(−1)。由于这种原因,如果使用cin.get( )(没有参数)并测试EOF,则必须将返回值赋给int变量,而不是char变量。另外,如果将ch的类型声明为int,而不是char,则必须在显示ch时将其强制转换为char类型。
-
int ch; // should be int, not charwhile ((ch = cin.get()) != EOF) // test for end-of-file{cout.put(char(ch));}
-
-
while.cpp
- 循环字符数组
- name[i] != ‘\0’
-
头文件ctime定义了一个符号常量—CLOCKS_PER_SEC,该常量等于每秒钟包含的系统时间单位数,将系统时间除以这个值,可以得到秒数
-
-
第六章代码
-
cctypes.cpp
-
#include
-
如果cin位于测试条件中,则将被转换为bool类型。如果输入成功,则转换后的值为true,否则为false
-
-
condit.cpp
- cin >> a >> b;
- 输入两个整数
-
enum.cpp
- enum {red, orange, yellow, green, blue, violet, indigo};
- 对应0-6
-
outfile.cpp
-
ofstream outFile;
-
outFile.open(“carinfo.txt”);
-
outFile << fixed; outFile.precision(2); outFile.setf(ios_base::showpoint); outFile << "Make and model: " << automobile << endl; outFile << "Year: " << year << endl; outFile << "Was asking $" << a_price << endl; outFile << "Now asking $" << d_price << endl;outFile.close(); // done with file
-
这里的outFile有点类似于cout
-
-
sumafile.cpp
-
ifstream inFile; if (!inFile.is_open()) // failed to open file {cout << "Could not open the file " << filename << endl;cout << "Program terminating.\n";// cin.get(); // keep window openexit(EXIT_FAILURE); } while (inFile.good()) // while input good and not at EOF {++count; // one more item readsum += value; // calculate running totalinFile >> value; // get next value } if (inFile.eof())cout << "End of file reached.\n"; else if (inFile.fail())cout << "Input terminated by data mismatch.\n"; elsecout << "Input terminated for unknown reason.\n"; if (count == 0)cout << "No data processed.\n"; else {cout << "Items read: " << count << endl;cout << "Sum: " << sum << endl;cout << "Average: " << sum / count << endl; } inFile.close();
-
输入格式不对,如将字符输入给double型,看inFile.fail()
-
到文件尾:inFile.eof()
-
-
-
第七章
-
arfupt.cpp
- 函数声明
- 参数列表const double ar [ ]与const double * ar的含义完全相同
- const函数,const double * f1(const double ar[], int n);返回一个常量指针
- 函数指针
- 函数指针,将函数名改为(*p1)即可,也可以用auto p2 = f2
- 函数指针调用时,可以加上(*p1)(av,3),也可以不用直接,p1(av,3)
- 函数数组
- pa是函数数组,不能直接auto pe = {f1,f2,f3};,要先定义pa这个函数数组,才能用auto pb = pa; pa的定义:函数指针数组,同理,改为(*pa[3])即可
- *函数数组指针的使用pa [i] (av,3) 或者 (pb[i]) (av,3)
数组名
和&数组名
的区别数组名
和&数组名
虽然在数值上相同,但是在类型上不同——数组名
是指向首个元素的指针,&数组名
是指向整个数组的指针。在指针加减整数的时候,前者以一个元素为颗粒度,后者以整个数组为颗粒度。- sizeof(array)是整个数组的
array
的值就等于&array[0]
的值- auto pc = &pa;用的时候加上*pc
- store return value
- const double * pdb = (*pd)[1] (av,3);
- 函数声明
-
arrfun2.cpp
- sum = sum_arr(cookies + 4, 4);
- 函数参数是数组的时候,可以数组名的偏移,思维打开
-
arrfun3.cpp
-
for (i = 0; i < limit; i++){cout << "Enter value #" << (i + 1) << ": ";cin >> temp;if (!cin) // bad input{cin.clear();while (cin.get() != '\n')continue;cout << "Bad input; input process terminated.\n";break;}else if (temp < 0) // signal to terminatebreak;ar[i] = temp;}
-
输入后,通过!cin判断是否是好的输入,若是不好,则cin.clear(),接着循环进行,直到get到回车,break;
-
void show_array(const double ar[], int n);
-
show的时候,要对这个数组加个const
-
-
arrfun4.cpp
-
int sum_arr(const int * begin, const int * end) {const int * pt;int total = 0;for (pt = begin; pt != end; pt++)total = total + *pt;return total; } sum = sum_arr(cookies + 4, cookies + 8);
-
-
arrobj.cpp
- void fill(std::array<double, Seasons> * pa);修改要加指针,(*pa)[i];
- fill(&expenses);
- void show(std::array<double, Seasons> da);
- show(expenses);
- 函数fill()和show()都有缺点。函数show()存在的问题是,expenses存
储了四个double值,而创建一个新对象并将expenses的值复制到其中的
效率太低。如果修改该程序,使其处理每月甚至每日的开支,这种问题
将更严重。show传参传入会复制一新对象,所以效率低下
-
funptr.cpp
- 函数指针作为参数
- void estimate(int lines, double (*pf)(int))
- (*pf)(lines)
- estimate(code, betsy);
- double betsy(int lns)
-
lotto.cpp
- unsigned本身是unsigned int的缩写
- cin >> total >> choicesk可以作逻辑词
-
ruler.cpp
-
包含多个递归调用的递归
-
subdivide( )函数使用变量level来控制递归层。函数调用自身时,将把level减1,当level为0时,该函数将不再调用自己。注意,subdivide( )调用自己两次,一次针对左半部分,另一次针对右半部分。最初的中点被用作一次调用的右端点和另一次调用的左端点。请注意,调用次数将呈几何级数增长。也就是说,调用一次导致两个调用,然后导致4个调用,再导致8个调用,依此类推。这就是6层调用能够填充64个元素的原因(2 6 =64)。这将不断导致函数调用数(以及存储的变量数)翻倍,因此如果要求的递归层次很多,这种递归方式将是一种糟糕的选择;然而,如果递归层次较少,这将是一种精致而简单的选择。
-
画尺子
-
subdivide(ruler,min,max, i);
-
i=1分一次,i=2分两次
-
for (int j = 1; j < Len - 2; j++)ruler[j] = ' '; // reset to blank ruler void subdivide(char ar[], int low, int high, int level) {if (level == 0)return;int mid = (high + low) / 2;ar[mid] = '|';subdivide(ar, low, mid, level - 1);subdivide(ar, mid, high, level - 1); }
-
-
-
strctptr.cpp
-
void rect_to_polar(const rect * pxy, polar * pda);
-
void show_polar (const polar * pda);
-
while (cin >> rplace.x >> rplace.y) {rect_to_polar(&rplace, &pplace); // pass addressesshow_polar(&pplace); // pass addresscout << "Next two numbers (q to quit): "; } //挺优雅的
-
-
strgback.cpp
-
// builds string made of n c characters char * buildstr(char c, int n) {char * pstr = new char[n + 1];pstr[n] = '\0'; // terminate stringwhile (n-- > 0)pstr[n] = c; // fill rest of stringreturn pstr; }
-
-
strgfun.cpp
-
const char * str, str是指针,可以++来遍历,*str是
-
unsigned int c_in_str(const char * str, char ch) {unsigned int count = 0;while (*str) // quit when *str is '\0'{if (*str == ch)count++;str++; // move pointer to next char}return count; }
-
-
structfun.cpp
-
#include
-
answer.distance =sqrt( xypos.x * xypos.x + xypos.y * xypos.y); answer.angle = atan2(xypos.y, xypos.x);
-
-
-
第八章代码
-
arrtemp.cpp
-
template <class T, size_t n> void display(const std::array<T, n> & ar);
-
模板类声明
-
这里用模板类
-
std::size_t是一个typedef,对应于合适的整型,在我的电脑上是long unsigned int
-
-
choices.cpp
-
template<class T> T lesser(T a, T b)
-
函数调用与模板函数和非模板函数都匹配,因此选择非模板函数,返回20。
-
lesser<>(m, n)有“<>”这个符号,一定是用模板
-
lesser(x, y),虽然输入x,y是double,但强行用int模板
-
-
filefunct.cpp
-
方法setf( )返回调用它之前有效的所有格式化设置。
-
同理,os.precision(0)也是
-
void file_it(ostream & os, double fo, const double fe[],int n)ios_base::fmtflags initial; initial = os.setf(ios_base::fixed, ios_base::floatfield); std::streamsize sz = os.precision(0);
-
ofstream是ostream的子类
-
-
funtemp.cpp
-
template <typename T> // or class T void Swap(T &a, T &b)
-
-
inline.cpp
- inline double square(double x) { return x * x; }
- 整个函数定义都放在一行中,但并不一定非得这样做。然而,如果函数定义占用多行(假定没有使用冗长的标识符),则将其作为内联函数就不太合适。
- 内联函数比宏好
- 宏不能按值传递,如当输入参数为4.5+7或者输入参数为c++,就不行
-
left.cpp
- char * left(const char * str, int n)
- 返回数组时,可以在函数里面new: char * p = new char[n+1];
- 但需要在外面delete
- char * left(const char * str, int n = 1);在函数原型的时候,=1,可以默认参数,这样不输入n参数时,默认n=1
-
leftover.cpp
-
计算位数如下:
-
unsigned digits = 1; while (n /= 10)digits++;
-
-
strquote.cpp
-
用const 修饰函数的返回值,如果给以“指针传递”方式的函数返回值加const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
-
例如函数: const char * GetString(void); 如下语句将出现编译错误: char *str = GetString(); 正确的用法是 const char *str = GetString(); 如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。 例如不要把函数int GetInt(void) 写成const int GetInt(void)。 函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。 class A { A & operate = (const A &other); // 赋值函数 }; A a, b, c; // a, b, c 为A 的对象 a = b = c; // 正常的链式赋值 (a = b) = c; // 不正常的链式赋值,但合法 如果将赋值函数的返回值加const 修饰,那么该返回值的内容不允许被改动。上例中,语句 a = b = c 仍然正确,但是语句 (a = b) = c 则是非法的。
-
const 成员函数(const的作用:说明其不会修改数据成员)
-
如果在编写const 成员函数时,不慎修改了数据成员,或者调用了其它非const 成员函数,编译器将指出错误 a. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数. b. const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的. c. const成员函数不可以修改对象的数据,不管对象是否具有const性质.它在编译时,以是否修改成员数据为依据,进行检查. e. 然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的。
-
const引用可以读取但是不可以被修改引用对象,任何对const引用进行赋值都是不合法的,它适用指向const对象的引用,而非const的引用不适用于指向const对象的引用。
-
-
swaps.cpp
-
通过引用来交换值
-
void swapr(int & a, int & b) // use references {int temp;temp = a; // use a, b for values of variablesa = b;b = temp; }
-
-
twoswap.cpp
-
可以提供一个具体化函数定义——称为显式具体化(explicit specialization),其中包含所需的代码。当编译器找到与函数调用匹配的具体化定义时,将使用该定义,而不再寻找模板。
-
template <typename T> void Swap(T &a, T &b); template <> void Swap<job>(job &j1, job &j2); //当参数为Job对象时,将使用显示具体化
-
-
tempover.cpp
- 当重载函数
- void ShowArray(T arr[], int n);
- void ShowArray(T * arr[], int n);
- 重载解析将寻找最匹配的函数。如果只存在一个这样的函数,则选择它;如果将模板B从程序中删除,则编译器将使用模板A来显示pd的内容,因此显示的将是地址,而不是值。
- 当重载函数
-
-
第九章代码
-
external.cpp support.cpp
-
::warming作用域解析运算符(::),放在变量名前面时,该运算符表示使用变量的全局版本。
-
extern double warming; // use warming from another file使用别的文件的全局变量,要用extern来声明它
-
CMakeLists.txt配置
-
add_library(support_library STATIC support.cpp ) add_executable(my_cmake_exe external.cpp) target_link_libraries( my_cmake_exe support_library )
-
-
file1.cpp coordin.h file2.cpp
- .h文件定义了结构体和函数原型
- file2.cpp实现了头文件的函数
- file1.cpp调用了该头文件中的函数
- 这里如果头文件在已知目录下,add_library(support_library STATIC file2.cpp )会自动去已知目录下找coordin.h因为file2.cpp里面有#include “coordin.h”
-
namesp.h namesp.cpp usenmsp.cpp
-
“namesp.h“中: namespace pers {定义结构体;函数原型; } namespace debts {using namespace pers;//使用刚定义的名称空间 }
-
“namesp.cpp“中: namespace pers {写函数 }
-
“usenmsp.cpp“中: using debts::Debt; using debts::showDebt; using namespace debts;
-
-
twofile1.cpp twofile2.cpp
-
twofile1.cpp使用twofile2.cpp的内容
-
twofile1.cpp中的int tom=3 twofile2.cpp使用extern int tom;
-
twofile1.cpp中的int dick = 30; twofile2.cpp使用static int dick = 10;
-
twofile1.cpp中的static int harry = 300; twofile2.cpp使用int harry = 200;
-
默认是extern
-
不能两个文件都int errors=3 这种做法将失败,因为它违反了单定义规则。file2中的定义试图创建一个外部变量,因此程序将包含errors的两个定义,这是错误。但如果文件定义了一个静态外部变量,其名称与另一个文件中声明的常规外部变量相同,则在该文件中,静态变量将隐藏常规外部变量.
-
-
newplace.cpp
-
定位new运算符
-
new运算符还有另一种变体,被称为定位(placement)new运算符,它让您能够指定要使用的位置。
-
char buffer[BUF]; // chunk of memory静态区
-
(void *) buffer来看内存地址
-
pd2 = new (buffer) double[N]; pd2 = new (buffer + N * sizeof(double)) double[N];
-
不需要delete,因为new的不在动态存储区
-
-
static.cpp
-
静态变量total只在程序运行时被设置为0,以后在两次函数调用之间,其值将保持不变,因此能够记录读取的字符总数。
-
using namespace std; char input[ArSize]; char next;cout << "Enter a line:\n"; cin.get(input, ArSize); while (cin) { cin.get(next); while (next != '\n') // string didn't fit! cin.get(next); // dispose of remainder strcount(input); cout << "Enter next line (empty line to quit):\n"; cin.get(input, ArSize); } cout << "Bye\n";
-
-
tip: C++也为静态存储持续性变量提供了3种链接性:外部链接性(可在其他文件中访问)、内部链接性(只能在当前文件中访问)和无链接性(只能在当前函数或代码块中访问)
-
补充:cv限定符,cv表示const和volatile
- 在C++看来,全局const定义(如下述代码段所示)就像使用了static说明符一样。
- const int finger = 10; same as ------ static const int finger = 10;
-
-
第十章代码
-
stock.h stock.cpp
-
通过内联函数来使得不需要重复输入计算代码
-
Stock(); // default constructor Stock(const std::string & co, long n = 0, double pr = 0.0); ~Stock(); // noisy destructor
-
默认构造函数
company = "no name"; shares = 0; share_val = 0.0; total_val = 0.0;
-
this是个对象指针,返回对象,要加*
-
使用对象指针的函数:&top->topval(stocks[st])
-
-
作用域为类的常量
-
一种方式是在类中声明一个枚举
用这种方式声明枚举并不会创建类数据成员。也就是说,所有对象中都不包含枚举。另外,Months只是一个符号名称,在作用域为整个类的代码中遇到它时,编译器将用30来替换它
-
另一种在类中定义常量的方式——使用关键字static
static const int Months = 12;
-
-
-
第十一章代码
-
运算符重载函数
-
Time operator+(const Time & t) const;
-
morefixing.operator+(total);
-
total = weeding + waxing;
-
Time operator*(double n) const; friend Time operator*(double m, const Time & t){ return t * m; } // inline definition //这样数*对象和对象*数都实现了
-
-
友元函数
-
通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的访问权限。
-
对于非成员重载运算符函数来说,运算符表达式左边的操作数对应于运算符函数的第一个参数,运算符表达式右边的操作数对应于运算符函数的第二个参数。
-
虽然该友元函数在类声明中声明,但是它不是成员函数,因此不能使用成员运算符来调用;
-
虽然该友元函数不是成员函数,但它与成员函数的访问权限相同
-
编写函数定义。因为它不是成员函数,所以不要使用Time::限定符。另外,不要在定义中使用关键字friend
-
加了const好像不能当左值:os << t.hours;所以std::ostream & os不能加const
-
std::ostream & operator<<(std::ostream & os, const Time & t) {os << t.hours << " hours, " << t.minutes << " minutes";return os; }//return os 因为才能在同一行多次<<
-
如果函数功能在其他函数实现了,可以调用其他函数:
-
friend Time operator*(double m, const Time & t){ return t * m; }
-
-
转换函数1
- 当构造函数只接受一个参数时,可以使用:Stonewt incognito = 257;
- Stonewt incognito(257);
- Stonewt incognito = Stonewt(257);
- 后两种也可以接受多参数输入
- 定义后,可以incognito = 276.8; taft = 325; same as taft = Stonewt(325);
- void display(const Stonewt & st, int n); display(422, 2);
-
转换函数2
- operator int() const; operator double() const;
- Stonewt poppins(9,2.8); 使用double p_wt = poppins; 时候会使用到
- int (poppins)也会使用到
- Vector Vector::operator-() const;当输入参数为0个时,为负号重载运算符
-
-
第十二章代码
-
stringbad.h stringbad.cpp vegnews.cpp
- 它使用char指针(而不是
char数组)来表示姓名。这意味着类声明没有为字符串本身分配存储空间,而是在构造函数中使用new来为字符串分配空间。这避免了在类声明中预先定义字符串的长度。 - 其次,将num_strings成员声明为静态存储类。只是为了方便说明静态数据成员,并指出潜在的编程问题,字符串类通常并不需要这样的成员。
- str = new char[len + 1];
- delete [] str;
- 传入const char * s,计算长度len = std::strlen(s);
- std::strcpy(str, s);
- 不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存。您可以使用这种格式来创建对象,从而分配和初始化内存。对于静态类成员,可以在类声明之外,如在stringbad.cpp而不是在头文件,使用单独的语句来进行初始
- 字符串并不保存在对象中。字符串单独保存在堆内存中,对象仅保存了指出到哪里去查找字符串的信息。
- 要创建字符串副本,所以不能直接str=s,防止重复释放
- 首先,将headline2作为函数参数来传递从而导致析构函数被调用。其次,虽然按值传递可以防止原始参数被修改,但实际上函数已使原始字符串无法识别,导致显示一些非标准字符(显示的文本取决于内存中包含的内容)。
- 主函数:创建了三个对象,一个用引用传递参数,一个用按值传递,一个复制构造函数,一个赋值运算符
- 默认复制构造是浅拷贝,按值传递参赛后,会调用,然后函数结束会自动析构,造成问题
- 因为自动存储对象被删除的顺序与创建顺序相反,所以最先删除的3个对象是knots、sailor和sport。
- StringBad knot;会调用默认构造函数,也是会创建对象的
- 在类声明初始化的静态:static const,enum
- 它使用char指针(而不是
-
sting1.h string1.cpp sayings1.cpp saying2.cpp
-
String::String(const char * s) // 构造函数 {len = std::strlen(s); // set sizestr = new char[len + 1]; // allot storagestd::strcpy(str, s); // initialize pointernum_strings++; // set object count }
-
String & String::operator=(const String & st) //赋值运算符 {if (this == &st)return *this;delete [] str;//先删除本身len = st.len;str = new char[len + 1];std::strcpy(str, st.str);return *this; }
-
new char[1]与new char分配内存量一致,但需要兼容delete []所以使用前者
-
delete[]与空指针兼容。因此也可用str = nullptr来指向空指针
-
-
返回对象将调用复制构造函数,而返回引用不会。
-
定位new运算符
-
将delete用于pc2和pc4时,将自动调用为pc2和pc4指向的对象调用析构函数;然而,将delete[]用于buffer时,不会为使用定位new运算符创建的对象调用析构函数。
-
pc3->~JustTesting(); // destroy object pointed to by pc3 pc1->~JustTesting(); // destroy object pointed to by pc1 delete [] buffer; // free buffer
对于使用定位new运算符创建的对象,应以与创建顺序相反的顺序进行删除。
原因在于,晚创建的对象可能依赖于早创建的对象。另外,仅当所有对象都被销毁后,才能释放用于存储这些对象的缓冲区。
-
-
C++11提供了另一种禁用方法的方式——使用关键字delete,与其将来面对无法预料的运行故障,不如得到一个易于跟踪的编译错误,指出这些方法是不可访问的。
-
C++为类构造函数提供了一种可用来初始化数据成员的特殊语法。这种语法包括冒号和由逗号分隔的初始化列表,被放在构造函数参数的右括号后,函数体的左括号之前。每一个初始化器都由被初始化的成员的名称和包含初始值的括号组成。从概念上来说,这些初始化操作是在对象创建时进行的,此时函数体中的语句还没有执行。语法如下:
- Queue::Queue(int qs) : qsize(qs),front(NULL){}
-
-
第十三章代码
-
public继承
- 使用公有派生,基类的公有成员将成为派生类的公有成员;基类的私有部分也将成为派生类的一部分,但只能通过基类的公有和保护方法访问
- 派生类对象包含基类对象。
- 派生类对象存储了基类的数据成员(派生类继承了基类的实现)、派生类对象可以使用基类的方法(派生类继承了基类的接口)。
- 派生类构造函数必须使用基类构造函数。
- 创建派生类对象时,程序首先创建基类对象。从概念上说,这意味着基类对象应当在程序进入派生类构造函数之前被创建。C++使用成员初始化列表语法来完成这种工作。
- 必须首先创建基类对象,如果不调用基类构造函数,程序将使用默认的基类构造函数
- 如果这个类没有使用动态内存分配,执行成员复制的隐式复制构造函数是合适的
- 释放对象的顺序与创建对象的顺序相反,即首先执行派生类的析构函数,然后自动调用基类的析构函数。
- 基类指针可以在不进行显式类型转换的情况下指向派生类对象;基类引用可以在不进行显式类型转换的情况下引用派生类对象
- 基类指针或引用只能用于调用基类方法,因此,不能使用rt或pt来调用派生类的ResetRanking方法
- 使用子类来初始化基类,存在隐式复制构造函数,隐式重载赋值运算符,基类部分被复制给它
- is-a继承关系,has-a成员关系
-
多态共有继承
-
希望同一个方法在派生类和基类中的行为是不同的。
-
Brass类和BrassPlus类都声明了ViewAcct( )和Withdraw( )方法,但BrassPlus对象和Brass对象的这些方法的行为是不同的;程序将使用对象类型来确定使用哪个版本:
-
Brass类在声明ViewAcct( )和Withdraw( )时使用了新关键字virtual。这些方法被称为虚方法(virtual method);对于在两个类中行为相同的方法,则只在基类中声明。
-
Brass类还声明了一个虚析构函数,虽然该析构函数不执行任何操作。
-
使用virtual,如果方法是通过引用或指针而不是对象调用的,它将确定使用哪一种方法。如果没有使用关键字virtual,程序将根据引用类型或指针类型选择方法;如果使用了virtual,程序将根据引用或指针指向的对象的类型来选择方法。因此,经常在基类中将派生类会重新定义的方法声明为虚方法。
-
虚析构函数:确保释放派生对象时,按正确的顺序调用析构函数,如果析构函数是虚的,将调用相应对象类型的析构函数。
-
如果析构函数是虚的,将调用相应对象类型的析构函数。
-
关键字virtual只用于类声明的方法原型中,而没有用于程序清单的方法定义中
-
非构造函数不能使用成员初始化列表语法,但派生类方法可以调用公有的基类方法。
-
如果代码没有使用作用域解析运算符,编译器将认为ViewAcct( )是BrassPlus::ViewAcct( ),这将创建一个不会终止的递归函数——这可不
好。 -
可以在类实现中写一些辅助函数,来防止代码重复
typedef std::ios_base::fmtflags format; typedef std::streamsize precis; format setFormat(); void restore(format f, precis p); format setFormat() {// set up ###.## formatreturn cout.setf(std::ios_base::fixed, std::ios_base::floatfield); } void restore(format f, precis p) {cout.setf(f, std::ios_base::floatfield);cout.precision(p); }
-
-
静态联编和动态联编
-
程序调用函数时,将使用哪个可执行代码块呢,在C++中,由于函数重载的缘故,这项任务更复杂。编译器必须查看函数参数以及函数名才能确定使用哪个函数在编译过程中进行联编被称为静态联编(static binding),又称为早期联编(early binding)。虚函数使这项工作变得更困难,编译器必须生成能够在程序运行时选择正确的虚方法的代码,这被称为动态联编(dynamic binding),又称为晚期联编(late binding)。
-
C++不允许将一种类型的地址赋给另一种类型的指针,也不允许一种类型的引用指向另一种类型;但是,指向基类的引用或指针可以引用派生类对象,而不必进行显式类型转换。
-
按值传递导致只将BrassPlus对象的Brass部分传递给函数fv( )。但随引用和指针发生的隐式向上转换导致函数fr( )和fp( )分别为Brass对象和BrassPlus对象使用Brass::ViewAcct( )和BrassPlus::ViewAcct( )。
-
通常,编译器处理虚函数的方法是:给每个对象添加一个隐藏成员。隐藏成员中保存了一个指向函数地址数组的指针。这种数组称为虚函数表(virtual function table,vtbl)。虚函数表中存储了为类对象进行声明的虚函数的地址。例如,基类对象包含一个指针,该指针指向基类中所有虚函数的地址表。派生类对象将包含一个指向独立地址表的指针。如果派生类提供了虚函数的新定义,该虚函数表将保存新函数的地址;如果派生类没有重新定义虚函数,该vtbl将保存函数原始版本的地
址。如果派生类定义了新的虚函数,则该函数的地址也将被添加到vtbl中(参见图13.5)。注意,无论类中包含的虚函数是1个还是10个,都只需要在对象中添加1个地址成员,只是表的大小不同而已。 -
使用虚函数时,在内存和执行速度方面有一定的成本,包括:每个对象都将增大,增大量为存储地址的空间;对于每个类,编译器都创建一个虚函数地址表(数组);对于每个函数调用,都需要执行一项额外的操作,即到表中查找地址。虽然非虚函数的效率比虚函数稍高,但不具备动态联编功能。
-
构造函数不能是虚函数。创建派生类对象时,将调用派生类的构造函数,而不是基类的构造函数,然后,派生类的构造函数将使用基类的一个构造函数,这种顺序不同于继承机制。因此,派生类不继承基类的构造函数,所以将类构造函数声明为虚的没什么意义。
-
析构函数应当是虚函数,除非类不用做基类。如果使用默认的静态联编,delete语句将调用~Employee( )析构函数。这将释放由Singer对象中的Employee部分指向的内存,但不会释放新的类成员指向的内存。但如果析构函数是虚的,则上述代码将先调用~Singer析构函数释放由Singer组件指向的内存,然后,调用~Employee()析构函数来释放由Employee组件指向的内存。
-
通常应给基类提供一个虚析构函数,即使它并不需要析构函数。
-
友元不能是虚函数,因为友元不是类成员,而只有成员才能是虚函数。如果由于这个原因引起了设计问题,可以通过让友元函数使用虚成员函数来解决。
-
新定义将showperks( )定义为一个不接受任何参数的函数。重新定义不会生成函数的两个重载版本,而是隐藏了接受一个int参数的基类版本。总之,重新定义继承的方法并不是重载。如果在派生类中重新定义函数,将不是使用相同的函数特征标覆盖基类声明,而是隐藏同名的基类方法,不管参数特征标如何。
也就是说:子类的virtual void showperks() const会覆盖掉virtual void showperks(int a)const
-
但如果返回类型是基类引用或指针,则可以修改为指向派生类的引用或指针(这种例外是新出现的)。这种特性被称为返回类型协变(covariance of return type),因为允许返回类型随类类型的变化而变化,这种例外只适用于返回值,而不适用于参数。
-
如果基类声明被重载了,则应在派生类中重新定义所有的基类版本如果不需要修改,则新定义可只调用基类版本:
-
所以要么如果子类和父类的方法一样,则要么不用虚函数,在父类用就行,要么就用虚函数,但是要重新定义基类版本
-
用vitual不同输入参数,但同函数名也会覆盖
-
-
protected:BrassPlus类可以直接访问balance,而不需要使用Brass方法。
-
抽象基类
- 从Ellipse和Circle类中抽象出它们的共性,将这些特性放到一个ABC中,然后从该ABC派生出Circle和Ellipse类。这样,便可以使用基类指针数组同时管理Circle和Ellipse对象,即可以使用多态方法)。
- 在这个例子中,这两个类的共同点是中心坐标、Move( )方法(对于这两个类是相同的)和Area( )方法(对于这两个类来说,是不同的)。确实,甚至不能在ABC中实现Area( )方法,因为它没有包含必要的数据成员。C++通过使用纯虚函数(pure virtual function)提供未实现的函数。纯虚函数声明的结尾处为=0
- 当类声明中包含纯虚函数时,则不能创建该类的对象。这里的理念是,包含纯虚函数的类只用作基类。要成为真正的ABC,必须至少包含一个纯虚函数。
- C++甚至允许纯虚函数有定义。例如,也许所有的基类方法都与Move( )一样,可以在基类中进行定义,但您仍需要将这个类声明为抽象的。在这种情况下,可以将原型声明为虚的:
-
派生类不使用new
- 是否需要为lackDMA类定义显式析构函数、复制构造函数和赋值运算符呢?不需要。
- 派生类的默认析构函数总是要进行一些操作:执行自身的代码后调用基类析构函数
- lacksDMA类的默认复制构造函数使用显式baseDMA复制构造函数来复制lacksDMA对象的baseDMA部分。因此,默认复制构造函数对于新的lacksDMA成员来说是合适的,同时对于继承的baseDMA对象来说也是合适的
- 类的默认赋值运算符将自动使用基类的赋值运算符来对基类组件进行赋值。因此,默认赋值运算符也是合适的。
-
派生类使用new
-
派生类析构函数自动调用基类的析构函数,故其自身的职责是对派生类构造函数执行工作的进行清理。
-
hasDMA复制构造函数只能访问hasDMA的数据,因此它必须调用baseDMA复制构造函数来处理共享的baseDMA数据
-
hasDMA::hasDMA(const hasDMA & hs): baseDMA(hs) // invoke base class copy constructor {style = new char[std::strlen(hs.style) + 1];std::strcpy(style, hs.style); }hasDMA::~hasDMA() {delete [] style; }hasDMA & hasDMA::operator=(const hasDMA & hs) {if (this == &hs)return *this;baseDMA::operator=(hs); // copy base portiondelete [] style; // prepare for new stylestyle = new char[std::strlen(hs.style) + 1];std::strcpy(style, hs.style);return *this; }
-
对于友元:
std::ostream & operator<<(std::ostream & os, const hasDMA & hs) {os << (const baseDMA &) hs;os << "Style: " << hs.style << std::endl;return os; }
-
-
-
第十四章代码
-
包含对象成员的类
- 使用这样的类成员:本身是另一个类的对象。这种方法称为包含(containment)、组合(composition)或层次化(layering)。
- 获得接口是is-a关系的组成部分。而使用组合,类可以获得实现,但不能获得接口。
- 将该typedef放在类定义的私有部分意味着可以在Student类的实现中使用它,但在Student类外面不能使用。
- explicit关闭隐式转换
- C++要求在构建对象的其他部分之前,先构建继承对象的所有成员对象。因此,如果省略初始化列表,C++将使用成员对象所属类的默认构造函数。
- 当初始化列表包含多个项目时,这些项目被初始化的顺序为它们被声明的顺序,而不是它们在初始化列表中的顺序。
-
使用私有或保护继承
-
使用私有继承,基类的公有成员和保护成员都将成为派生类的私有成员。
-
私有继承提供的特性与包含相同:获得实现,但不获得接口。
-
新的Student类不需要私有数据,因为两个基类已经提供了所需的所有数据成员。
-
对于继承类,新版本的构造函数将使用成员初始化列表语法,它使用类名而不是成员名来标识构造函数:
-
访问基类的方法:
- ArrayDb::size() > 0 使用私有继承
- scores.size() > 0 不使用私有继承
-
Student类的代码如何访问内部的string对象呢?
-
使用强制类型转换
return (const string &) *this;
-
-
访问基类的友元函数
-
通过显式地转换为基类来调用正确的函数
-
ostream & operator<<(ostream & os, const Student & stu) {os << "Scores for " << (const string &) stu << ":\n";stu.arr_out(os); // use private method for scoresreturn os; }
-
-
-
使用包含还是私有继承
- 继承会引起很多问题,尤其从多个基类继承时,可能必须处理很多问题,如包含同名方法的独立的基类或共享祖先的独立基类。
- 包含能够包括多个同类的子对象。如果某个类需要3个string对象,可以使用包含声明3个独立的string成员。而继承则只能使用一个这样的对象(当对象都没有名称时,将难以区分)。
- 私有继承所提供的特性确实比包含多,通过继承得到的将是派生类,因此它
能够访问保护成员。 - 另一种需要使用私有继承的情况是需要重新定义虚函数。派生类可以重新定义虚函数,但包含类不能。使用私有继承,重新定义的函数将只能在类中使用,而不是公有的。
- 公有继承可以隐式向上转换,私有继承不可以隐式向上转换
- 保护继承只能在派生类中隐式向上转换,不能在外面
- 使用保护派生或私有派生时,基类的公有成员将成为保护成员或私有成员。假设要让基类的方法在派生类外面可用,方法之一是定义一个使用该基类方法的派生类方法。另一种方法是,将函数调用包装在另一个函数调用中,即使用一个using声明(就像名称空间那样)来指出派生类可以使用特定的基类成员,即使采用的是私有派生。using声明只使用成员名——没有圆括号、函数特征标和返回类型。
-
多重继承使得能够使用两个或更多的基类派生出新的类,将基类的功能组合在一起
-
如果添加一个从Singer和Waiter类派生出的SingingWaiter类后,将带来一些问题。具体地说,将出现以下问题。有多少Worker ,哪个方法?
-
继承两个基类对象,包含两个Worker对象拷贝
-
C++引入多重继承的同时,引入了一种新技术——虚基类(virtual base class),使MI成为可能
-
虚基类使得从多个类(它们的基类相同)派生出的对象只继承一个基类对象。
-
通过在类声明中使用关键字virtual,可以使Worker被用作Singer和Waiter的虚基类
-
现在,SingingWaiter对象将只包含Worker对象的一个副本。从本质上说,继承的Singer和Waiter对象共享一个Worker对象,而不是各自引入自己的Worker对象副本。因为SingingWaiter现在只包含了一个Worker子对象,所以可以使用多态。
-
使用虚基类时,需要对类构造函数采用一种新的方法。对于非虚基类,唯一可以出现在初始化列表中的构造函数是即时基类构造函数。
SingingWaiter(const Worker & wk, int p = 0, int v = other): Worker(wk), Waiter(wk,p), Singer(wk,v) {}
-
对于哪个方法的问题,可以使用对象.Singer::Show().
-
Singer::show();
-
使用虚基类将改变C++解析二义性的方式。使用非虚基类时,规则很简单。如果类从不同的类那里继承了两个或更多的同名成员(数据或方法),则使用该成员名时,如果没有用类名进行限定,将导致二义性。但如果使用的是虚基类,则这样做不一定会导致二义性。在这种情况下,如果某个名称优先于(dominates)其他所有名称,则使用它时,即便不使用限定符,也不会导致二义性。派生类中的名称优先于直接或间接祖先类中的相同名称。任何一个omg( )定义都不优先于其他omg( )定义,因为C和E都不是对方的基类。所以,在F中使用非限定的omg( )将导致二义性。
-
-
类模板
-
不能将模板成员函数放在独立的实现文件中,模板必须与特定的模板实例化请求一起使用。
-
template <class T, int n> class ArrayTP { private:T ar[n]; public:ArrayTP() {};explicit ArrayTP(const T & v);virtual T & operator[](int i);virtual T operator[](int i) const; };
-
递归使用模板 ArrayTP<ArrayTP<int,5>,10> twodee
-
使用多个类型参数 Pair<string, int>
-
默认类型模板参数
-
-
模板的具体化
- 隐式实例化
- 显式实例化
- 显式具体化
- 部分具体化
-
成员模板
-
模板可用作结构、类或模板类的成员
-
template <typename T> class beta { private:template <typename V> // nested template class memberclass hold{private:V val;
-
嵌套模板
-
-
将模板作为参数
- template <template class Thing>
- Crab nebula;
-
模板类和友元
- 非模板友元函数与模板类
- 模板友元函数与模板类
-
-
第十五章代码
-
友元类
-
class Tv { public:friend class Remote;
-
-
友元类方法
-
class Tv; // forward declarationclass Remote {
-
事实上,唯一直接访问Tv成员的Remote方法是Remote::set_chan( ),因此它是唯一
需要作为友元的方法。确实可以选择仅让特定的类成员成为另一个类的友元,而不必让整个类成为友元,但这样做稍微有点麻烦,必须小心排列各种声明和定义的顺序。 -
在编译器在Tv类的声明中看到Remote的一个方法被声明为Tv类的友元之前,应该先看到Remote类的声明和set_chan( )方法的声明。
-
-
嵌套类
- 在C++中,可以将类声明放在另一个类中。在另一个类中声明的类被称为嵌套类(nested class),它通过提供新的类型类作用域来避免名称混乱。包含类的成员函数可以创建和使用被嵌套类的对象;
-
引发异常、try块和catch块
-
异常类
-
运行阶段类型识别(RTTI)
-
dynamic_cast和typeid
-
static_cast、const_cast和reiterpret_cast
-
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- OpenJudge - 1490:A Knight‘s Journey
骑士厌倦了一次又一次地看到相同的黑白方块,并决定环游世界。每当骑士移动时,它都是一个方向上的两个正方形和一个垂直于此方向的正方形。骑士的世界就是他所生活的棋盘。我们的骑士住在一个棋盘上,这个棋盘的面积比普通的8 * 8棋盘小&#x…...
2024/4/13 13:52:29 - Kafka producer的事务和幂等性
背景:kafka 客户端之producer API发送消息以及简单源码分析 从Kafka 0.11开始,KafkaProducer又支持两种模式:幂等生产者和事务生产者。幂等生产者加强了Kafka的交付语义,从至少一次交付到精确一次交付。特别是生产者的重试将不再…...
2024/5/6 6:15:09 - 图腾的由来
如今的世界,还是科技领导着的时候,大家都用心来发展科技生产力。这些特性便是大家用共同的经历铸就而来的,遇强则强遇难而上永不退缩。...
2024/4/19 18:24:40 - 出圈-java
题目描述: 设有n个人围坐一圈并按顺时针方向从1到n编号,从第1个人开始进行1到m的报数,报数到第个m人,此人出圈,再从他的下一个人重新开始1到m的报数,如此进行下去直到所剩下一人为止。 输入: 输…...
2024/4/16 21:31:22 - Unity 如何延时运行或者重复运行函数?
1.Invoke(函数名称字符串,几秒种后执行); 这种调用方法只会执行一次。 2.InvokeRepeating(函数名称字符串,几秒钟后开始,间隔秒数);这种调用方法就像一个计时器,是执行多次的。 具体参考 https://jingyan.baidu.com/article/0eb457e5ccbf8f03f0a9057a.html...
2024/4/13 13:52:34 - build_process-webpack的构建流程
webpack的构建流程? 一、运行流程 webpack 的运行流程是一个串行的过程,它的工作流程就是将各个插件串联起来 在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条webpack机制中,去改变webpack的运作…...
2024/4/14 1:30:40 - pytorch本地图片数据集加载成字典
from torchvision.transforms import transforms import pandas as pdfile_pathos.path.join(rE:\python存储\leaves\images) Image_list[] labels_list[] a{}for i in range(0,18352):image_pathos.path.join(rE:\python存储\leaves\images,{}.jpg.format(i))imageImage.open(…...
2024/4/13 13:52:54 - 如何改变晶振频率?
简 介: 本文就拆开的一个普通的晶体进行观察,构建了 Colpittz振荡电路,并对晶体表面留下记号笔痕迹后谐振频率的改变进行了测量。这种方法可以对晶体的谐振频率进行修改,反过来也可以用于测量微小质量的改变。 关键词:…...
2024/4/13 13:52:29 - java 重载、重写 构造函数详解
1、重写只能出现在继承关系之中。当一个类继承它的父类方法时,都有机会重写该父类的方法。一个特例是父类的方法被标识为final。重写的主要优点是能够定义某个子类型特有的行为。 复制代码 class Animal { public void eat(){ System.out.println ("Animal is …...
2024/4/19 22:18:10 - AcWing 1875. 贝茜的报复(数学+暴力枚举)
题目连接 https://www.acwing.com/problem/content/1877/ 思路 我们顺着不太好计算,所以我们反着计算,计算出所有满足条件的奇数个数,然后相乘就好了,复杂度为O(N4)O(N^4)O(N4), 代码 #include<bits/stdc.h> using nam…...
2024/4/13 13:52:34 - AcWing 1904. 奶牛慢跑(单调栈)
题目连接 https://www.acwing.com/problem/content/1906/ 思路 如果一个牛比前面的牛跑的还慢那么就可以把这两个牛合并,如果相同的话就不要合并了,所以我们最后构造的就是一个速度非严格单调递增的序列 #include<bits/stdc.h> using namespac…...
2024/4/7 21:28:43 - JavaScript 基础笔记(pink老师)-- 对象
JavaScript 基础笔记(pink老师)-- 对象...
2024/4/15 5:17:59 - 数学建模竞赛时间表(全年11场数模竞赛)
大家好,我是北海。今天整理了下常见的数模竞赛时间,按竞赛正常举办时间顺序排序。 1、美国大学生数学建模竞赛 主办方:美国数学及其应用联合会 竞赛时间:寒假期间,春节前后 2、MathorCup高校数学建模挑战赛 主办方…...
2024/4/13 13:53:29 - sqli-labs(Less62-65)布尔类型脚本
Less-62Less-63Less-64Less-65Less-62 import requests from lxml import etree""" Less-62布尔类型爆破脚本 改源码$times 13000,重置一下challenges数据库,然后启动程序,包没下先pip下载 原理是按照payload循环字典,根据响应的长度&am…...
2024/4/16 8:40:42 - (未学习)从零开始学习C++ Day 016
本科郑州大学应用化学系,研究生福州大学物理化学,后从事营地教育两年,现在跨专业考研至计算机。 写这个文章记录的初衷是希望通过这样的方式来监督自己每日学习一定量的编程保持练习,虽然初试的成绩还未出。但只要有一线希望自然…...
2024/4/20 12:12:31 - redis夺命连环问11--集群模式工作原理能说一下么?集群模式下的key是如何寻址的?分布式寻址都有哪些算法?了解一致性hash算法吗?
目录Redis集群模式的工作原理能说一下么?首先谈数据分区规则再谈分区具体方案最后谈实例通信机制盲目扩大集群规模,实例间的通信量也会增加,集群性能变慢,如何降低实例间的通信开销?在集群模式下,redis 的 …...
2024/4/30 16:52:10 - 02.25 Chat Servers Outgoing Traffic聊天服务流量输出
聊天服务器传出流量|断续器 (jxnu.edu.cn)https://acs.jxnu.edu.cn/problem/CF5A 描述: Polycarp is working on a new project called "Polychat". Following modern tendencies in IT, he decided, that this project should contain chat as well. To…...
2024/4/18 12:53:46 - JAVA入门-面向对象
类:是对一切相似事物的统称.是一个泛泛的概念。可以用来描述事物的特征和行为 对象:就是一个具体的实体。 类和对象的关系: 对象是类的具体的实现,在类下面延伸出来具体对象 在java中先有类 再有对象 一、声明一个类 语法格…...
2024/4/13 15:56:10 - Redis安装和启动所遇到的问题
Redis安装和启动所遇到的问题 1、到redis官网https://redis.io/下载所需版本的压缩包(源码包) 2、将linux版本的redis上传到指定服务器目录(我的目录是: /usr/java) 3、将压缩包进行解压,解压到指定目录&a…...
2024/4/13 13:53:49 - AcWing 1929. 镜子田地(DFS)
题面连接 https://www.acwing.com/problem/content/description/1931/ 思路 因为光路可逆,那么对于每一个点的方向就是固定的,也就是入射角和反射角,那么对于每一个点的走向我们都是可以提前预知的,所以我们直接对每个外圈点进…...
2024/4/13 13:53:34
最新文章
- C# 与 Qt 的对比分析
C# 与 Qt 的对比分析 目录 C# 与 Qt 的对比分析 1. 语言特性 2. 开发环境 3. 框架和库 4. 用户界面设计 5. 企业级应用 6. 性能考量 在软件开发领域,C# 和 Qt 是两种常用的技术栈,它们分别在.NET平台和跨平台桌面应用开发中占据重要位置。本文将深…...
2024/5/6 6:48:55 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - 递归的基本思想
递归解决问题的思路是将大问题拆解成更小的同类问题,并通过解决这些更小的问题来解决原始问题。这种方法适用于问题可以被分解成相似的子问题的情况。 递归的基本要素: 基础情况(Base Case):递归函数中需要有一个或多…...
2024/5/4 5:34:47 - Python读取文件里内容
如果要读取一个文件里的内容是 # 文件名:db.txt 1 2 3 4代码如下 import requests f open("db.txt", mode"rb") content f.read() f.close()data content.decode(utf-8)# 存到 list 里 data_list data.split(\r\n) print(data_list)# 结果…...
2024/5/5 8:37:34 - Android 关机充电动画卡住无反应,也不灭屏
充电动画: 1.普通充电 2.快速充电: 原因:低电关机充电,电压升压导致充电逻辑混乱,5v到9v时,导致充电动画卡死。 办法:删掉原来的快充通道,替换为普通充电通道! /vend…...
2024/5/5 8:26:33 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/4 23:54:56 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/4 23:54:56 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/5/4 23:54:56 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/4 23:55:17 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/5/4 23:54:56 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/5/4 23:55:05 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/5/4 23:54:56 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/5/4 23:55:16 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/5/4 23:54:56 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/6 1:40:42 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/5/4 23:54:56 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/5/4 23:55:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/5/4 23:55:06 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/5/4 23:54:56 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/4 23:55:06 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/5 8:13:33 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/5/4 23:55:16 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/5/4 23:54:58 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/4 23:55:01 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/5/4 23:54:56 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57