C++ new 可以很方便的 分配一段内存。
比如 int *test= new int ; int n; cin>>n; int * test =new int [n]; 可以实现动态分配内存,比c的malloc 简洁多了,
同样也能new 一个 结构体。总之挺方便的。
new 之后 不用了 要用delet free 内存
另外对空指针delete 是安全的。
模板类:vector,也是一种动态数组。
用法 vector<typename> vt {n_elem};
模板类:array,不是动态滴~
用法 array<typename,n_elem> vt {};
C++的for循环多了一种新特性:可以基于范围。
for(double x:nums){x=x*100;}
在for中 用于循环用的++i 和i++ 前缀格式和后缀格式,前缀格式 就将值加一,然后返回。
但后缀版本会首先复制一个副本,将其加1,然后将其复制的副本返回。
但是经过我 ida 看汇编的结构,确是相反的,这个问题
main proc near ; CODE XREF: _main_0↑j.text:00414920.text:00414920 var_D8 = byte ptr -0D8h.text:00414920 j = dword ptr -14h.text:00414920 i = dword ptr -8.text:00414920.text:00414920 push ebp.text:00414921 mov ebp, esp.text:00414923 sub esp, 0D8h.text:00414929 push ebx.text:0041492A push esi.text:0041492B push edi.text:0041492C lea edi, [ebp+var_D8].text:00414932 mov ecx, 36h.text:00414937 mov eax, 0CCCCCCCCh.text:0041493C rep stosd.text:0041493E mov [ebp+i], 0.text:00414945 jmp short loc_414950.text:00414947 ; ---------------------------------------------------------------------------.text:00414947.text:00414947 loc_414947: ; CODE XREF: _main+65↓j.text:00414947 mov eax, [ebp+i].text:0041494A add eax, 1.text:0041494D mov [ebp+i], eax.text:00414950.text:00414950 loc_414950: ; CODE XREF: _main+25↑j.text:00414950 cmp [ebp+i], 5.text:00414954 jge short loc_414987.text:00414956 mov esi, esp.text:00414958 push offset j_??$endl@DU?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@@Z ; std::endl>(std::basic_ostream > &).text:0041495D mov edi, esp.text:0041495F mov eax, [ebp+i].text:00414962 push eax.text:00414963 mov ecx, ds:__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A.gap0 ; std::basic_ostream > std::cout.text:00414969 call ds:__imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream >::operator<<(int).text:0041496F cmp edi, esp.text:00414971 call j___RTC_CheckEsp.text:00414976 mov ecx, eax.text:00414978 call ds:__imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream >::operator<<(std::basic_ostream > & (*)(std::basic_ostream > &)).text:0041497E cmp esi, esp.text:00414980 call j___RTC_CheckEsp.text:00414985 jmp short loc_414947.text:00414987 ; ---------------------------------------------------------------------------.text:00414987.text:00414987 loc_414987: ; CODE XREF: _main+34↑j.text:00414987 mov [ebp+j], 0.text:0041498E jmp short loc_414999.text:00414990 ; ---------------------------------------------------------------------------.text:00414990.text:00414990 loc_414990: ; CODE XREF: _main+AE↓j.text:00414990 mov eax, [ebp+j].text:00414993 add eax, 1.text:00414996 mov [ebp+j], eax.text:00414999.text:00414999 loc_414999: ; CODE XREF: _main+6E↑j.text:00414999 cmp [ebp+j], 5.text:0041499D jge short loc_4149D0.text:0041499F mov esi, esp.text:004149A1 push offset j_??$endl@DU?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@@Z ; std::endl >(std::basic_ostream > &).text:004149A6 mov edi, esp.text:004149A8 mov eax, [ebp+j].text:004149AB push eax.text:004149AC mov ecx, ds:__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A.gap0 ; std::basic_ostream > std::cout.text:004149B2 call ds:__imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream >::operator<<(int).text:004149B8 cmp edi, esp.text:004149BA call j___RTC_CheckEsp.text:004149BF mov ecx, eax.text:004149C1 call ds:__imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream >::operator<<(std::basic_ostream > & (*)(std::basic_ostream > &)).text:004149C7 cmp esi, esp.text:004149C9 call j___RTC_CheckEsp.text:004149CE jmp short loc_414990
for (i = 0; i < 5; i++) { cout << i << endl; } for (j = 0; j < 5; ++j) { cout << j << endl; }
恰恰相反。
const 这个标志符的作用也蛮大的,可以防止数据被修改,但是如果是一个指针指向一个变量,这个指针用了const,这样这个指针就不能修改这个数据,但是还是可以通过变量名字修改。
比较有趣的是函数指针,int (*pd)(int ); 可以直接把指针指向函数名就能执行了。用tpyedef 也能定义。挺有趣的。
今天在leetcode 做一道题的时候,遇到了一个问题:
runtime error: member access within null pointer of type 'struct ListNode'
while(l1!=NULL||l2!=NULL){ sum=0; if(l1->next!=NULL) { y=l1->val;l1=l1->next; } if(l2->next!=NULL) { y=l2->val; l2=l2->next; }
我就用了这种方法,后来想了想,看了下别人的,发现这个错误在哪里了,如果l1 或者l2 有一个已经为NULL的时候,这时还能进入while中,但是如果 (l1->next或者l2->next)的时候,那个已经为空的指针就会访问到,但是他是NULL NULL并没有->next利用引用,因为他不是ListNode 结构体。
今天也了解到 hashmap,hashmap 在遍历里面的元素时所用的时间复杂度为O(1);这样在某些题目中可以用空间获取时间来获得最优解。
Mapmap = new HashMap<>();
map 有不少内置的方法可以使用,还不错。