奶头挺立呻吟高潮av全片,成人试看120秒体验区,性欧美极品v,A片高潮抽搐揉捏奶头视频

C語言

C++中時間與時間戳的轉換

時間:2024-11-01 16:55:27 C語言 我要投稿
  • 相關推薦

C++中時間與時間戳的轉換

  C語言把括號、賦值、強制類型轉換等都作為運算符處理。從而使C語言的運算類型極其豐富,表達式類型多樣化。下面是小編分享的C++中時間與時間戳的轉換,一起來看一下吧。

C++中時間與時間戳的轉換

  C++ 中時間與時間戳的轉換實例

  // 設置時間顯示格式:

  NSString *timeStr = @"2011-01-26 17:40:50";

  [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ----------設置你想要的格式,hh與HH的區別:分別表示12小時制,24小時制。

  //設置時區,這個對于時間的處理有時很重要。

  //例如你在國內發布信息,用戶在國外的另一個時區,你想讓用戶看到正確的發布時間就得注意時區設置,時間的換算。

  //例如你發布的時間為2010-01-26 17:40:50,那么在英國愛爾蘭那邊用戶看到的時間應該是多少呢?

  //他們與我們有7個小時的時差,所以他們那還沒到這個時間呢...那就是把未來的事做了。

  NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];

  [formatter setTimeZone:timeZone];

  NSDate *date = [formatter dateFromString:timeStr]; //------------將字符串按formatter轉成nsdate

  NSLog(@"date = %@", date);

  NSDate *datenow = [NSDate date];//現在時間,你可以輸出來看下是什么格式

  NSLog(@"datenow = %@", datenow);

  NSString *nowtimeStr = [formatter stringFromDate:datenow];//----------將nsdate按formatter格式轉成nsstring,nsstring會顯示與當前的時間吻合的串

  NSLog(@"nowtimeStr = %@", nowtimeStr);

  // 時間轉時間戳的方法:

  NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];

  NSLog(@"timeSp:%@",timeSp); //時間戳的值

  // 時間戳轉時間的方法

  NSDate *confromTimesp = [NSDate dateWithTimeIntervalSince1970:1296035591];

  NSLog(@"1296035591 = %@",confromTimesp);

  NSString *confromTimespStr = [formatter stringFromDate:confromTimesp];

  NSLog(@"confromTimespStr = %@",confromTimespStr);

  // 時間戳轉時間的方法:

  NSDateFormatter* formatter1 = [[NSDateFormatter alloc] init];

  [formatter1 setDateStyle:NSDateFormatterMediumStyle];

  [formatter1 setTimeStyle:NSDateFormatterShortStyle];

  [formatter1 setDateFormat:@"yyyyMMddHHMMss"];

  NSDate *date1 = [formatter1 dateFromString:@"1283376197"];

  NSLog(@"date1:%@",date1);

  當前時間是:14:41:57

  C/C++內存管理

  內存分配方式

  簡介

  在C++中,內存分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。

  棧:在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置于處理器的指令集中,效率很高,但是分配的內存容量有限。

  堆:就是那些由 new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個 。如果程序員沒有釋放掉,那么在程序結束后,操作系統會自動回收。

  自由存儲區:就是那些由malloc等分配的內存塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。

  全局/靜態存儲區:全局變量和靜態變量被分配到同一塊內存中,在以前的C語言中,全局變量又分為初始化的和未初始化的,在C++里面沒有這個區分了,他們共同占用同一塊內存區。

  常量存儲區:這是一塊比較特殊的存儲區,他們里面存放的是常量,不允許修改。

  常見的內存錯誤及其對策

  發生內存錯誤是件非常麻煩的事情。編譯器不能自動發現這些錯誤,通常是在程序運行時才能捕捉到。而這些錯誤大多沒有明顯的癥狀,時隱時現,增加了改錯的難度。有時用戶怒氣沖沖地把你找來,程序卻沒有發生任何問題,你一走,錯誤又發作了。

  常見的內存錯誤及其對策如下:

  內存分配未成功,卻使用了它。編程新手常犯這種錯誤,因為他們沒有意識到內存分配會不成功。常用解決辦法是,在使用內存之前檢查指針是否為NULL。如果指針p是函數的參數,那么在函數的入口處用assert(p!=NULL)進行檢查。如果是用malloc或new來申請內存,應該用if(p==NULL) 或if(p!=NULL)進行防錯處理。

  內存分配雖然成功,但是尚未初始化就引用它。犯這種錯誤主要有兩個起因:一是沒有初始化的觀念;二是誤以為內存的缺省初值全為零,導致引用初值錯誤(例如數組)。內存的缺省初值究竟是什么并沒有統一的標準,盡管有些時候為零值,我們寧可信其無不可信其有。所以無論用何種方式創建數組,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。

  內存分配成功并且已經初始化,但操作越過了內存的邊界。例如在使用數組時經常發生下標“多1”或者“少1”的操作。特別是在for循環語句中,循環次數很容易搞錯,導致數組操作越界。

  忘記了釋放內存,造成內存泄露。含有這種錯誤的函數每被調用一次就丟失一塊內存。剛開始時系統的內存充足,你看不到錯誤。終有一次程序突然死掉,系統出現提示:內存耗盡。動態內存的申請與釋放必須配對,程序中malloc與free的使用次數一定要相同,否則肯定有錯誤(new/同理)。

  釋放了內存卻繼續使用它。

  有三種情況:

  (1). 程序中的對象調用關系過于復雜,實在難以搞清楚某個對象究竟是否已經釋放了內存,此時應該重新設計數據結構,從根本上解決對象管理的混亂局面。

  (2). 函數的return語句寫錯了,注意不要返回指向“棧內存”的“指針”或者“引用”,因為該內存在函數體結束時被自動銷毀。

  (3). 使用free或釋放了內存后,沒有將指針設置為NULL。導致產生“野指針”。

  那么如何避免產生野指針呢?這里列出了5條規則,平常寫程序時多注意一下,養成良好的習慣。

  規則1:用malloc或new申請內存之后,應該立即檢查指針值是否為NULL。防止使用指針值為NULL的內存。

  規則2:不要忘記為數組和動態內存賦初值。防止將未被初始化的內存作為右值使用。

  規則3:避免數組或指針的下標越界,特別要當心發生“多1”或者“少1”操作。

  規則4:動態內存的申請與釋放必須配對,防止內存泄漏。

  規則5:用free或釋放了內存之后,立即將指針設置為NULL,防止產生“野指針”。

  C/C++函數調用的方式

  棧是一種先進后出的數據結構,棧有一個存儲區、一個棧頂指針。棧頂指針指向堆棧中第一個可用的數據項(被稱為棧頂)。用戶可以在棧頂上方向棧中加入數據,這個操作被稱為壓棧(Push),壓棧以后,棧頂自動變成新加入數據項的位置,棧頂指針也隨之修改。用戶也可以從堆棧中取走棧頂,稱為彈出棧(pop),彈出棧后,棧頂下的一個元素變成棧頂,棧頂指針隨之修改。函數調用時,調用者依次把參數壓棧,然后調用函數,函數被調用以后,在堆棧中取得數據,并進行計算。函數計算結束以后,或者調用者、或者函數本身修改堆棧,使堆;謴驮b。

  在參數傳遞中,有兩個重要的問題必須要明確說明:

  1. 當參數個數多于一個時,按照什么順序把參數壓入堆棧;

  2. 函數調用后,由誰來把堆;謴驮瓲。

  在高級語言中,就是通過函數的調用方式來說明這兩個問題的。常見的調用方式有:

  stdcall

  cdecl

  fastcall

  thiscall

  thiscall

  naked call

  下面就分別介紹這幾種調用方式:

  1.stdcall

  stdcall調用方式又被稱為Pascal調用方式。在Microsoft C++系列的C/C++編譯器中,使用PASCAL宏,WINAPI宏和CALLBACK宏來指定函數的調用方式為stdcall。

  stdcall調用方式的函數聲明為:

  int stdcall function(int a, int b);

  stdcall的調用方式意味著:

  (1) 參數從右向左一次壓入堆棧

  (2) 由被調用函數自己來恢復堆棧

  (3) 函數名自動加前導下劃線,后面緊跟著一個@,其后緊跟著參數的尺寸

  上面那個函數翻譯成匯編語言將變成:

  push b 先壓入第二個參數

  push a 再壓入第一個參數

  call function 調用函數

  在編譯時,此函數的名字被翻譯為function@8

  2.cdecl

  cdecl調用方式又稱為C調用方式,是C語言缺省的調用方式,它的語法為:

  int function(int a, int b) // 不加修飾符就是C調用方式

  int cdecl function(int a, int b) // 明確指定用C調用方式

  cdecl的調用方式決定了:

  (1) 參數從右向左依次壓入堆棧

  (2) 由調用者恢復堆棧

  (3) 函數名自動加前導下劃線

  由于是由調用者來恢復堆棧,因此C調用方式允許函數的參數個數是不固定的,這是C語言的一大特色。

  此方式的函數被翻譯為:

  push b // 先壓入第二個參數

  push a // 在壓入第一個參數

  call funtion // 調用函數

  add esp, 8 // 清理堆棧

  在編譯時,此方式的函數被翻譯成:function

  3.fastcall

  fastcall 按照名字上理解就可以知道,它是一種快速調用方式。此方式的函數的第一個和第二個DWORD參數通過ecx和edx傳遞,

  后面的參數從右向左的順序壓入棧。

  被調用函數清理堆棧。

  函數名修個規則同stdcall

  其聲明語法為:

  int fastcall function(int a, int b);

  4.thiscall

  thiscall 調用方式是唯一一種不能顯示指定的修飾符。它是c++類成員函數缺省的調用方式。由于成員函數調用還有一個this指針,因此必須用這種特殊的調用方式。

  thiscall調用方式意味著:

  參數從右向左壓入棧。

  如果參數個數確定,this指針通過ecx傳遞給被調用者;如果參數個數不確定,this指針在所有參數壓入棧后被壓入棧。

  參數個數不定的,由調用者清理堆棧,否則由函數自己清理堆棧。

  可以看到,對于參數個數固定的情況,它類似于stdcall,不定時則類似于cdecl。

  5.naked call

  是一種比較少見的調用方式,一般高級程序設計語言中不常見。

  函數的聲明調用方式和實際調用方式必須一致,必然編譯器會產生混亂。

  函數名字修改規則:

  1.C編譯時函數名修飾約定規則:

  stdcall調用約定在輸出函數名前加上一個下劃線前綴,后面加上一個“@”符號和其參數的字節數,格式為function@8。

  cdecl調用約定僅在輸出函數名前加上一個下劃線前綴,格式為function。

  fastcall調用約定在輸出函數名前加上一個“@”符號,后面也是一個“@”符號和其參數的字節數,格式為@function@8。

  它們均不改變輸出函數名中的字符大小寫,這和PASCAL調用約定不同,PASCAL約定輸出的函數名無任何修飾且全部大寫。

  2.C++編譯時函數名修飾約定規則:

  stdcall調用約定:

  (1)以“?”標識函數名的開始,后跟函數名;

  (2)函數名后面以“@@YG”標識參數表的開始,后跟參數表;

  (3)參數表以代號表示:

  X--void ,

  D--char,

  E--unsigned char,

  F--short,

  H--int,

  I--unsigned int,

  J--long,

  K--unsigned long,

  M--float,

  N--double,

  N--bool,

  PA--表示指針,后面的代號表明指針類型,如果相同類型的指針連續出現,以“0”代替,一個“0”代

  表一次重復;

  (4)參數表的第一項為該函數的返回值類型,其后依次為參數的數據類型,指針標識在其所指數據類型前;

  (5)參數表后以“@Z”標識整個名字的結束,如果該函數無參數,則以“Z”標識結束。

  其格式為“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”,例如

  int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z”

  void Test2() -----“?Test2@@YGXXZ”

  cdecl調用約定:

  規則同上面的stdcall調用約定,只是參數表的開始標識由上面的“@@YG”變為“@@YA”。

  fastcall調用約定:

  規則同上面的stdcall調用約定,只是參數表的開始標識由上面的“@@YG”變為“@@YI”。

  VC++對函數的省缺聲明是"cedcl",將只能被C/C++調用。

  關于C/C++ 表達式求值順序

  i = ++i + 1; // The behavior is unspecified

  在介紹概念之前,我們先解釋一下它的結果。這個表達式( expression )包含3個子表達式( subexpression ):

  e1 = ++i

  e2 = e1 + 1

  i = e2

  這三個子表達式都沒有順序點( sequence point ),而 ++ i 和 i = e3 都是有副作用( side effect )的表達式。由于沒有順序點,語言不保證這兩個副作用的順序。

  更加可怕的是,如果i 是一個內建類型,并在下一個順序點之前被改寫超過一次,那么結果是未定義(undefined)的!比如本例中如果有:

  int i = 0x1000fffe;

  i = ++i + 1; // The result is undefined!!

  你也許會認為他的結果是加1 或者加2,其實更糟糕 —— 結果可能是 0x1001ffff 。他的高字節接受了一個副作用的內容,而低字節則接受了另一個副作用的內容! 如果i 是指針,那么將很容易造成程序崩潰。

  為什么要這么做呢?因為對于編譯器提供商來說,未確定的順序對優化有相當重要的作用。比如,一個常見的優化策略是“減少寄存器占用和臨時對象”。編譯器可以重新組織表達式的求值,以便盡量不使用額外的寄存器以及臨時變量。 更加嚴格的說,即使是編譯器提供商也無法完全徹底序列化指令(比如無法嚴格規定讀和寫的順序),因為CPU本身有權利修改指令順序,以便達到更高的速度。

  下面的術語以 ISO C99 和 C++03為準。譯名為參考并附帶原術語對照,如有解釋不當或者錯誤望指正。

  表達式有兩種功能。每個表達式都產生一個值( value ),同時可能包含副作用( side effect ),比如:他可能修改某些值。

  規則的核心在于 順序點( sequence point ) [ C99 6.5 Expressions 條款2 ] [ C++03 5 Expressions 概述 條款4 ]。 這是一個結算點,語言要求這一側的求值和副作用(除了臨時對象的銷毀以外)全部完成,才能進入下面的部分。 C/C++中大部分表達式都沒有順序點,只有下面五種表達式有:

  1 函數。函數調用之前有一個求值順序點。

  2 && || 和 ?: 這三個包含邏輯的表達式。其左側邏輯完成后有一個求值順序點。

  3 逗號表達式。逗號左側有一個求值順序點。

  注意,他們都只有一個求值順序點,2和3的右側運算結束后并沒有求值順序點。

  在兩個順序點之間,子表達式求值和副作用的順序是不確定的。假如代碼的結果與求值和副作用發生順序相關,我們稱這樣的代碼有不確定的行為(unspecified behavior)。 而且,假如期間對一個內建類型執行一次以上的寫操作,則是未定義行為(undefined behavior)——我們知道,未定義行為帶來最好的后果是讓你的程序立即崩掉。

  n = n++; // 兩個副作用,對于內建對象產生是未定義行為

  幾乎所有表達式,求值順序都不確定。比如,下面的加法, f1 f2 f3的調用順序是任意的:

  n = f1() + f2() + f3(); // f1 f2 f3 調用順序任意

  而函數也只在實際調用前有一個求值順序點。所以,常見于早期 C 語言教材的這類題目,是錯題:

  printf("%d",--a+b,--b+a); // --a + b 和 --b + a 這兩個子表達式,求值順序不確定

  天啊,甚至可能出現未定義行為?那么堅決不寫與實現相關的代碼是最好的對策。即使是不確定行為(比如函數調用時) 只要沒有順序點編譯器怎么做方便就怎么做。 有些人認為函數調用參數求值與入棧順序相關,這是一種誤導。這個東西要解釋,無異于事后諸葛亮:

  void f( int i1, int i2, int i3, int i4 ){

  cout<< i1 << ' ' << i2 << ' ' << i3 << ' ' << i4 << endl;}

  int main(){

  int i = 0;

  f( i++, i++, i++, i++ );}

  這個有四個表達式求值,同時每個表達式都有負作用。這八個操作順序是任意的,那么結果如何?未定義。

  請用 VC7.1 Debug和 Release 分別測試這同一份代碼,結果是不同的:

  0 0 0 0 [release]

  3 2 1 0 [debug]

  事實上,鑒于前面的討論,如果換一些其他初始值,這里甚至會出現錯位而得到千奇百怪的詭異結果。

  再看看C/C++標準中的其他經典例子:

  [C99] 6.5.2.2 Function call

  條款12 EXAMPLE 在下面的函數調用中:

  (*pf[f1()]) ( f2(), f3() + f4() )

  函數 f1 f2 f3 和f4 可能以任何順序被調用。 但是,所有副作用都必須在那個 pf[ f1() ] 返回的函數指針產生的調用前完成。

  [C++03] 5 Expressions 概論4

  i = v[i++]; // the behavior is unspecified

  i = 7, i++, i++; // i becomes 9 ( 譯注: 賦值表達式比逗號表達式優先級高 )

  i = ++i + 1; // the behavior is unspecified

  i = i + 1; // the value of i is incremented

  More Effective C++ 告誡我們, 千萬不要重載 &&, || 和, 操作符[ MEC ,條款7 ]。為什么?

  以逗號操作符為例,每個逗號左側有一個求值順序點。假如ar是一個普通的對象,下面的做法是無歧義的:

  ar[ i ], ++i ;

  但是,如果ar[ i ] 返回一個 class A 對象或引用,而它重載了 operator, 那么結果不妙了。那么,上面的語句實際上是一個函數調用:

  ar[ i ].operator, ( ++i );

  C/C++ 中,函數只在調用前有一個求值順序點。所以 ar[i] 和 ++i 的求值、以及 ++i 副作用的順序是任意的。這會引起混亂。

  更可怕的是,重載 && 和 || 。 大家已經習慣了其速死算法: 如果左側求值已經決定了最終結果,則右側不會被求值。而且大家很依賴這個行為,比如是C風格字符串拷貝常常這樣寫:

  while( p && *p )

  *pd++ = *p++;

  假如p 為 0, 那么 *p 的行為是未定義的,可能令程序崩潰。 而 && 的求值順序避免了這一點。 但是,如果我們重載 && 就等于下面的做法:

  exp1 .operator && ( exp2 )

  現在不僅僅是求值混亂了。無論exp1是什么結果,exp2 必然會被求值。

  C與C++的變量聲明

  如何理解C和C++的復雜類型聲明,曾經碰到過讓你迷惑不解、類似于int * (* (*fp1) (int) );這樣的變量聲明嗎?本文將由易到難,一步一步教會你如何理解這種復雜的C/C++ 聲明,我們將從天天都能碰到的較簡單的聲明入手,然后逐步加入const修飾符和typedef,還有函數指針,最后介紹一個能夠讓你準確地理解任何C/C++ 聲明的“右左法則”,需要強調一下的是,復雜的C/C++ 聲明并不是好的編程風格;我這里僅僅是教你如何去理解這些聲明。注重:為了保證能夠在同一行上顯示代碼和相關注釋,本文最好在至少1024x768分辨率的顯示器上閱讀。

  讓我們從一個非常簡單的例子開始,如下:

  int n;

  這個應該被理解為www.diannao114.cn “declare n as an int”(n是一個int型的變量)。接下去來看一下指針變量,如下:

  int *p;

  這個應該被理解為“declare p as an int *”(p是一個int *型的變量),或者說p是一個指向一個int型變量的指針。我想在這里展開討論一下:我覺得在聲明一個指針(或引用)類型的變量時,最好將*(或 &)寫在緊靠變量之前,而不是緊跟基本類型之后。這樣可以避免一些理解上的誤區,比如:

  int* p;//不推薦

  再來看一個指針的指針的例子:

  char **argv;

  理論上,對于指針的級數沒有限制,你可以定義一個浮點類型變量的指針的指針的指針的指針,再來看如下的聲明:

  int RollNum[30][4];

  int (*p)[4]=RollNum;

  int *q[5];

  這里,p被聲明為一個指向一個4元素(int類型)數組的指針,而q被聲明為一個包含5個元素(int類型的指針)的數組。另外,我們還可以在同一個聲明中混合實用*和&,如下:

  int **p1;// p1 is a pointer to a pointer to an int.

  int *&p2;// p2 is a reference to a pointer to an int.

  int &*p3;// ERROR: Pointer to a reference is illegal.

  int &&p4;// ERROR: Reference to a reference is illegal.

  注:p1是一個int類型的指針的指針;p2是一個int類型的指針的引用;p3是一個int類型引用的指針(不合法!);p4是一個int類型引用的引用(不合法。。

  const 修飾符

  當你想阻止一個變量被改變,可能會用到const要害字。在你給一個變量加上const修飾符的同時,通常需要對它進行初始化,因為以后的任何時候你將沒有機會再去改變它。例如:

  const int n=5;

  int const m=10;

  上述兩個變量n和m其實是同一種類型的變量,都是const int(整形恒量)。因為C 標準規定,const要害字放在類型或變量名之前等價的。我個人更喜歡第一種聲明方式,因為它更突出了const修飾符的作用。當const與指針一起使用時,輕易讓人感到迷惑。例如,我們來看一下下面的p和q的聲明:

  const int *p;

  int const *q;

  他們當中哪一個代表const int類型的指針(const直接修飾int),哪一個代表int類型的const指針(const直接修飾指針)?實際上,p和q都被聲明為const int類型的指針。而int類型的const指針應該這樣聲明:

  int * const r= &n;// n has been declared as an int

  這里,p和q都是指向const int類型的指針,也就是說,你在以后的程序里不能改變*p的值。而r是一個const指針,它在聲明的時候被初始化指向變量n(即r=&n;)之后,r的值將不再答應被改變(但*r的值可以改變)。

  組合上述兩種const修飾的情況,我們來聲明一個指向 const int類型的const指針,如下:

  const int * const p=&n// n has been declared as const int

  下面給出的一些關于const的聲明,將幫助你徹底理清const的用法。不過請注重,下面的一些聲明是不能被編譯通過的,因為他們需要在聲明的同時進行初始化。為了簡潔起見,我忽略了初始化部分;因為加入初始化代碼的話,下面每個聲明都將增加兩行代碼。

  char **p1;// pointer to pointer to char

  const char **p2;// pointer to pointer to const char

  char * const * p3;// pointer to const pointer to char

  const char * const * p4;// pointer to const pointer to const char

  char ** const p5;// const pointer to pointer to char

  const char ** const p6;// const pointer to pointer to const char

  char * const * const p7;// const pointer to const pointer to char

  const char * const * const p8;// const pointer to const pointer to const char

  注: p1是指向char類型的指針的指針;p2是指向const char類型的指針的指針;p3是指向char類型的const指針;p4是指向const char類型的const指針;p5是指向char類型的指針的const指針;p6是指向const char類型的指針的const指針;p7是指向char類型const指針的const指針;p8是指向const char類型的const指針的const指針。

【C++中時間與時間戳的轉換】相關文章:

PHP時間轉換Unix時間戳代碼08-19

如何利用PHP時間轉換Unix時間戳代碼10-21

php日期轉時間戳 指定日期轉換成時間戳09-26

C++類的轉換10-17

2017中考備戰時間表07-23

2024年中考考試時間06-08

2015中西醫執業醫師報名時間確定09-01

時間介詞短語07-30

認識時間教案08-19

2017中級經濟師報名時間及資格審核09-26

主站蜘蛛池模板: 福贡县| 滨海县| 资兴市| 凌云县| 宜君县| 库伦旗| 汝南县| 库车县| 东阿县| 牙克石市| 阿荣旗| 淅川县| 阿拉善左旗| 磴口县| 桃园市| 梅河口市| 黑河市| 屯门区| 嘉荫县| 延吉市| 融水| 永平县| 平安县| 松江区| 赤壁市| 樟树市| 遵化市| 揭东县| 额济纳旗| 色达县| 柳河县| 磐安县| 丹凤县| 渭南市| 昭觉县| 基隆市| 阳泉市| 府谷县| 安平县| 东城区| 神池县|