C/C++知識點清單01

来源:http://www.cnblogs.com/Tiancheng-Duan/archive/2017/07/12/7125622.html
-Advertisement-
Play Games

第一章 C/C++程式基礎 一、一般賦值語句: 考察一般賦值語句的概念和方法。 1.程式: 2.答案: 3.分析: 代碼行.12中的“&”表示位與計算,即將y和z轉換為二進位數字10和10,進行位與計算。1&1=1,其餘都是0,故結果為二進位10。所以答案為2,x=2。 代碼行.16中的“|”表示位 ...


第一章  C/C++程式基礎

一、一般賦值語句:

考察一般賦值語句的概念和方法。

1.程式:

 1 #include<stdio.h>
 2 
 3 int main(void)
 4 {
 5     int x=3,y,z;
 6 
 7     x*=(y=z=4);    printf("x=%d\n",x);
 8 
 9     z=2;
10     x=(y=z);    printf("x=%d\n",x);
11     x=(y==z);    printf("x=%d\n",x);
12     x=(y&z);    printf("x=%d\n",x);
13     x=(y&&z);    printf("x=%d\n",x);
14 
15     y=4;
16     x=(y|z);    printf("x=%d\n",x);
17     x=(y||z);    printf("x=%d\n",x);
18 
19     x=(y==z)? 1:(y<z)? 2:3;
20     printf("x=%d\n",x);
21 
22     return 0;
23 }

 

2.答案:

   x=12
   x=2
   x=1
   x=2
   x=1
   x=6
   x=1
   x=5
   x=3

 

3.分析:

  代碼行.12中的“&”表示位與計算,即將y和z轉換為二進位數字10和10,進行位與計算。1&1=1,其餘都是0,故結果為二進位10。所以答案為2,x=2。

  代碼行.16中的“|”表示位或計算,方法同上。0|0=0,其餘都是1,故結果為二進位110。所以答案為6,x=6。

 

4.小結:

  一般賦值語句,記住符號的優先順序即可。另外記住一些特殊的運算符,如位計算符、三目運算符。

  

  

  

   (圖片來自網路資源)

 

 

二、C++域操作符:

1.程式:

 1 #include<stdio.h>
 2 
 3 int value=0;
 4 
 5 void printvalue()
 6 {
 7     printf("value=%d\n",value);
 8 };
 9 
10 int main()
11 {
12     int value=0;
13 
14     value=1;
15     printf("value=%d\n",value);
16 
17     ::value=2;
18     printvalue();
19 
20     return 0;
21 }

 

2.答案:

(C++中輸出)

value=2        //局部變數value
value=1        //全局變數value

PS:C語言下無法編譯通過。

 

3.分析:

  這段程式包含著兩個value變數。其中一個是在main函數前就聲明的全局變數,另一個是在main函數內部聲明的局部變數。這兩者作用域是不同的(局部變數只可以作用魚定義它的函數內部)。

  在main函數中代碼行.15中輸出的是局部變數value的值(value=1)。這是因為在main函數中的局部變數value引用優先。在C++中可以通過域操作符“::”來直接操作全局變數(代碼行.17改變了全局變數value的值)。在之後的代碼行.18中調用printvalue函數輸出全局變數value的值(value=2)。

 

 

三、i++與++i哪個效率更高:

  其實,單純考慮首碼自增運算和尾碼自增運算是沒有意義的。首先考慮內建數據類型的情況:如果自增運算表達式的結果沒有被使用,而只是用於增加一員操作數,那麼兩者沒有任何區別。主要需要查看自定義數據類型的情況。

1.程式:

 1 #include<stdio.h>
 2 
 3 int main()
 4 {
 5     int i=0;
 6     int x=0;
 7 
 8     i++;
 9     ++i;
10     x=i++;
11     x=++i;
12 
13     return 0;
14 }

  經過VC++6.0編譯,得到如下彙編代碼:

;Line 5
 mov DWORD PTR _i$[ebp],0
Line 6
 mov DWORD PTR _x$[ebp],0
Line 8
 mov eax,DWORD PTR _i$[ebp]
 add eax,1
 mov DWORD PTR _i$[ebp],eax
Line 9
 mov ecx,DWORD PTR _i$[ebp]
 add ecx,1
 mov DWORD PTR _i$[ebp],ecx
Line 10
 mov edx,DWORD PTR _i$[ebp]
 mov DWORD PTR _x$[ebp],edx
 mov eax,DWORD PTR _i$[ebp]
 add eax,1
 mov DWORD PTR _i$[ebp],eax 
Line 11
 mov ecx,DWORD PTR _i$[ebp]
 add ecx,1
 mov DWORD PTR _i$[ebp],ecx
 mov edx,DWORD PTR _i$[ebp]
 mov DWORD PTR _x$[ebp],edx

 

2.答案:

  內建數據類型,效率沒有區別。

  自定義數據類型,++i效率更高。

 

3.分析:

  代碼行.8-9生成的彙編代碼幾乎完全一致。

  代碼行.10-11生成的彙編代碼只是在加1的先後順序上有所區別,效率也完全一致。

  由此說明,考慮內建數據類型時,它們的效率差別不大。

  那麼再考慮自定義數據類型(主要指類)的情況,由於首碼式(++i)可以返回對象的引用,而尾碼式(i++)必須返回對象的值,從而導致在大對象的時候產生較大的複製開銷,引起效率降低。故自定義數據類型時,首碼式遞增/遞減效率更高。

 

4.小結:

  表示分析中的最後一段,估計很多如我一般的萌新都感覺不是很懂。所以經過百度和查閱後,給大家一個翻譯後的解釋。

  (以下代碼來自博客:為什麼(i++)不能做左值,而(++i)可以
    // 首碼形式:
  int& int::operator++()
     //這裡返回的是一個引用形式,就是說函數返回值也可以作為一個左值使用
  {
        //函數本身無參,意味著是在自身空間內增加1的
    *this += 1;      // 增加
    return *this;      // 取回值
  }

  //尾碼形式:
  const int int::operator++(int)
     //函數返回值是一個非左值型的,與首碼形式的差別所在。
  {
        //函數帶參,說明有另外的空間開闢
    int oldValue = *this;  // 取回值
    ++(*this);  // 增加
    return oldValue;  // 返回被取回的值
  }

  故++i與i++兩者的具體實現函數的不同造成在引用時,兩者所占據的資源不同。

 

 

四、選擇編程風格良好的條件選擇語句:

1.程式:

 A.布爾型:假設布爾變數名字為flag,它與零值比較的標準if語句如下:

  第一種:

1     if(flag==TRUE)
2     if(flag==FALSE)

  第二種:

1     if(flag)
2     if(!flag)

 B.整型:假設整型變數的名字為value,它與零值比較的標準if語句如下:

  第一種:

1     if(value==0)
2     if(value!=0)

  第二種:

1     if(value)
2     if(!value)

 C.浮點型:假設浮點變數的名字為x,它與零值比較的標準if語句如下:

  第一種:

1     if(x==0.0)
2     if(x!0.0)

  第二種:

1     if((x>=-EPSINON)&&(X<=EPSINON))
2     if((X<-EPSINON)||(X>EPSINON))

PS:其中EPSINON為允許的誤差(精度)。

 D.指針型:指著變數p與0的比較如下:

  第一種:

1     if(p==NULL)
2     if(p!=NULL)

  第二種:

1     if(p==0)
2     if(p!=0)

 

2.答案:

 A:後者風格較為良好。

 B:前者風格較為良好。

 C:後者風格較為良好。

 D:前者風格較為良好。

 

3.分析:

 A:根據布爾類型的語義,零值為“假”(記為FALSE),任何非零值都是“真”(記為TRUE)。TRUE的值並沒有統一的標準。因此,不可將布爾變數直接與TURE、FALSE進行比較。

 B:後者風格容易令人誤解value為布爾變數。所以應該將整型變數用“==”與“!=”直接與0比較。

 C:浮點型變數都有精度限制。一定要極力避免將浮點變數通過“==”或“!=”與數字進行比較,應該設法轉化為精度與“>=”、“<=”間的比較。(論證在C教程上)

 D:指針變數的零值為“空”(記為NULL)。儘管NULL的值與0相同,但是兩者意義不同。用p與NULL顯式比較,強調p是指針。

 

 

五、有符號變數與無符號變數的值的轉換:

(有符號變數和無符號變數的區別:http://blog.csdn.net/gogokongyin/article/details/39758289)

1.程式:

 1 #include<stdio.h>
 2 
 3 char getChar(int x,int y)
 4 {
 5     char c;
 6     unsigned int a=x;
 7 
 8     (a+y>10)? (c=1):(c=2);
 9     return c;
10 }
11 
12 int main(void)
13 {
14     char c1=getChar(7,4);
15     char c2=getChar(7,3);
16     char c3=getChar(7,-7);
17     char c4=getChar(7,-8);
18 
19     printf("c1=%d\n",c1);
20     printf("c2=%d\n",c2);
21     printf("c3=%d\n",c3);
22     printf("c4=%d\n",c4);
23 
24     return 0;
25 }

 

2.答案:

    c1=1
    c2=2
    c3=2
    c4=1

 

3.分析:

  在getChar函數中,有兩個整型的輸入參數x和y。在函數內,把參數x的值轉換為無符號(unsigned)整型後再與y相加。之後再與10比較。

  註意:在表達式中存在有符號類型和無符號類型時,所有的操作數都自動隱式轉換成無符號類型。

  代碼行.14中,傳入的參數分別為7和4,兩個數相加後為11,因此c1返回1。

  代碼行.15中,傳入的參數分別為7和3,兩個數相加後為10,因此c2返回2。

  代碼行.16中,傳入的參數分別為7和-7,在signed下,-7為7的原碼00000000 00000111的反碼11111111 11111000加1,得到其補碼11111111 11111001。在signed下,整數通過16位開頭第一位區別正負,0為整數,1為負數。餘下的15位才是真正的數欄位。但是unsigned下,是沒有負數的,也就是說整整16位都是數欄位。所以signed下的-7,在unsigned下轉化為65529。那麼7和65529相加後為65536,這個值得大小正好溢出(unsigned int數據範圍為0-65535共計65536個數字)(實際得到的結果為0)。因此c3返回2。

PS:我只按照16位解釋,將位數增加到32位也是沒有區別的。

  代碼行.17中,傳入的參數分別為7和-8,實際轉化方式如上,最終相加得到的值為65535。因此c4返回1。

 

4.小結:

  其實這個程式難點在於兩處:一方面,要知道有符號、無符號的概念與區別;另一方面,知道原碼、反碼、補碼的計算。

  當然,你十分熟悉這個過程,一眼就看出來也行。通過7+(-7)=0,知道-7為是否溢出的負數上限,看出負數中[-65535,-8]滿足條件,[-7,-1]會導致溢出(正數大家都可以一眼看出)。

 

 

 六、不使用任何中間變數如何將a、b的值進行轉換:

  表示這個問題我在剛學編程是就想過,因為我們老師說轉換兩者值必須中間變數,然後我就想出通過加、減(下麵程式第二個方法)寫出代碼,給老師看去了。

  表示我“打”老師臉最開心的幾次。淡定ing。

1.程式:

 1 #include<stdio.h>
 2 
 3 void swap1(int& a,int& b)
 4 {
 5     int temp=a;    //使用局部變數temp完成交換
 6     a=b;
 7     b=temp;
 8 };
 9 
10 void swap2(int& a, int& b)
11 {
12     a=a+b;    //使用加減運算完成交換
13     b=a-b;
14     a=a-b;
15 };
16 
17 void swap3(int& a,int& b)
18 {
19     a^=b;    //使用異或運算完成交換
20     b^=a;
21     a^=b;
22 };
23 
24 int main(void)
25 {
26     int a1=1,b1=2;
27     int a2=3,b2=4;
28     int a3=5,b3=6;
29     int a=2147483647,b=1;
30 
31     swap1(a1,b1);    //測試使用臨時變數進行交換的版本
32     swap2(a2,b2);    //測試使用加減運算進行交換的版本
33     swap3(a3,b3);    //測試使用異或運算進行交換的版本
34 
35     printf("after swap...\n");
36     printf("a1=%d,b1=%d\n",a1,b1);
37     printf("a2=%d,b2=%d\n",a2,b2);
38     printf("a3=%d,b3=%d\n",a3,b3);
39 
40     swap2(a,b);
41     printf("a=%d,b=%d\n",a,b);
42 
43     return 0;
44 }

 

2.答案:

    after swap...
    a1=2,b1=1;
    a2=4,b2=3;
    a3=6,b3=5;
    a1=1,b1=2147483647

 

3.分析:

  首先,swap1函數就不談了。通過一個中間變數temp來達到交換目的。其次,swap2函數就是通過a,b的和與差來進行轉化,也就是需要對數學有一定的基礎和靈性。

  之後,就是一個小重點(沒辦法,學校C課程對位運算提到原碼,補碼,反碼),那就是通過位運算中的異或運算來實現數值轉換。

 

4.小結:

  其實從某種角度上來說第三種方法時前兩種方法的綜合。一方面,這個方法存在中間變數,那就是代碼行.19中的最終結果a。另一方面,這個方法將這個中間變數保存在了兩個變數中的變數a。之所以沒說這個方法和第二種一致,是因為它只用了兩個變數中的一個變數存儲中間變數就是實現了最終目的。所以,我很喜歡它。

 

 

 七、標準頭文件的結構:

考察標準頭文件中一些通用結構的理解。

1.程式:

 1 #ifndef _INCvxWorksh
 2 #define _INCvxWorksh
 3 #ifdef _cplusplus
 4 extern "C" {
 5 #endif
 6 /*...*/
 7 #ifdef _cplusplus
 8 }
 9 #endif
10 #endif /* _INCvxWorksh */

 

2.答案:

  代碼行.1,2,10中代碼的作用是防止頭文件被重覆引用。

  代碼行.3中代碼的作用是表示當前使用的是C++編譯器。

  代碼行.4-8中的extern"C"是C++編譯器提供的與C連接交換指定的符號,用來解決名字匹配問題。

 

3.分析:

  代碼行.1,2,10中代碼是為了防止頭文件的重覆引用。因為常常一個CPP文件有多個頭文件,而頭文件之間又是可以相互引用的,這就可能造成頭文件的重覆引用,當頭文件被重覆引用時,編譯器就會報錯,顯示頭文件被重覆定義。

  那麼避免重覆引用頭文件有兩種方法:

   1.使用 ifndef/define/endif 結構產生預處理塊

    優點:由於這個語句是語言相關的,可移植性好。

    缺點:由於只有打開了某個頭文件,編譯器才能根據保護巨集確定是否引用過了。所以效率相對較低。但是這種方法是通過保護巨集名來確定某個頭文件是否被引用過,那麼巨集名重覆,就出現需要的頭文件明明就在那裡,編譯器卻說找不到這個頭文件(因為那個頭文件因為保護巨集名重覆而被屏蔽了)。

   2.使用 #pragma once

    優點:由編譯器提供保證,同一個文件不會被包含兩次(這裡的包含指的是物理地址,即文件的路徑地址)。所以效率較高。

    缺點:由於頭文件的屏蔽是編譯器通過頭文件物理地址的記錄來實現的。所以如果某一個頭文件有多個複製的副本,依舊會造成頭文件重覆引用的問題。

       另外這個方法只能在微軟開發工具上實現。很多編譯器沒有,或者有這個方法的編譯器打算移除。

    (PS:上述部分資料引用於http://blog.csdn.net/zhl30041839/article/details/37728237)

 

  代碼行.3表明瞭當前使用的編譯器為C++編譯器。如果需要表明為C編譯器,則語句可以表示為“#indef _STDC_”。

  代碼行.4-8中 extern "C"包含著雙重意義。這句話主要由兩個部分“extern”與“C”組成。

    前者是C/C++的一個重要關鍵字,用於表明其修飾的變數和函數作用範圍。extern表明其聲明的變數和函數可以在本模塊或其他模塊中使用。通常,在模塊的頭文件中對本模塊提供給其他模塊引用的函數和全局變數以關鍵字extern聲明。在模塊的頭文件中對本模塊提供給其它模塊引用的函數和全局變數以關鍵字extern聲明。例如,如果模塊B欲引用該模塊A中定義的全局變數和函數時只需包含模塊A的頭文件即可。這樣,模塊B中調用模塊A中的函數時,在編譯階段,模塊B雖然找不到該函數,但是並不會報錯;它會在連接階段中從模塊A編譯生成的目標代碼中找到此函數。

    (PS:上述部分資料引用於http://www.cnblogs.com/skynet/archive/2010/07/10/1774964.html)

    後者表示其修飾的變數和函數是按照C語言的方式編譯和連接的。由於C++支持函數重載,而過程式語言C則不支持,故C++和C語言的函數編譯是存在不同的。

    例如:“void foo(int x,int y);”與“void foo(int x,float y);”在C++語言也許會被編譯為“_foo_int_int”與“_foo_int_float”(C++通過這種機制來實現函數重載),但在C語言編譯中都是“_foo”。這就會造成在C中連接C++編譯的函數符號時,就會因此找不到匹配的符號而發生連接錯誤。如果添加了extern“C”聲明後,模塊編譯會生成foo的目標代碼時,就不會對其名字進行特殊處理,而採用C語言的方式處理(也就是不會添加參數表信息)。

 

 

八、#include<head.h>與#include"head.h"的區別:

1.答案:

  尖括弧<>表明其中的文件head.h是一個工程或者標準頭文件。所以編譯器會在查找過程中優先檢查預定義的目錄。當然,我們可以通過設置搜索路徑環境變數或命令行選項來修改這些目錄。

  引號""表明其中的文件head.h是有用戶提供的頭文件。所以編譯器在查找過程中會優先從當前文件目錄(或文件名指定的其他目錄)中尋找該文件,然後再在標準位置尋找文件。

 

 

九、C++中main函數執行完後還需要執行的語句:

1.程式:

 1 #include<stdlib.h>    //使用atexit()函數必須包含頭文件stdlib.h
 2 #include<stdio.h>
 3 
 4 void fn1(void);
 5 void fn2(void);
 6 
 7 int main(void)
 8 {
 9     atexit(fn1);        //使用atexit註冊fn1()函數
10     atexit(fn2);        //使用atexit註冊fn2()函數
11     printf("main exit...\n");
12     return 0;
13 }
14 
15 void fn1()
16 {
17     printf("calling fn1()...\n");    //fn1()函數列印內容
18 }
19 
20 void fn2()
21 {
22     printf("calling fn2()...\n");    //fn2()函數列印內容
23 }

 運行結果:

    main exit...
    calling fn2()...
    calling fn1()...

 

2.答案:

  可以通過atexit()函數(at-exit)來註冊程式正常終止時要被調用的函數,並且在main()函數結束時,調用這些函數順序和註冊它們的順序相反。

 

3.分析:

  我們常常需要在程式結束時解決一些類似資源釋放的操作,但是程式退出的方法很多(有興趣的可以看看WIN32編程中提及的),所以我們需要一個一種與程式退出方式無關的方式,來進行那些在程式退出時進行的必要操作。

  atexit()函數就是這樣一個滿足條件的函數,它通過註冊程式正常終止時需要被調用的函數。其函數原型為:

1         int atexit (void (*)(void));

  在一個程式中最多可以通過atexit()函數註冊32個必要處理函數。不過這些必要處理函數的調用順序和它們的註冊順序恰好相反。

  (PS:有時也有一些有關進程關閉的語句會令這個函數無法使用,具體可以參照百度百科-atexit)

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MD5的簡介:MD5即Message-Digest Algorithm 5(信息-摘要演算法5),用於確保信息傳輸完整一致。是電腦廣泛使用的雜湊演算法之一(又譯摘要演算法、哈希演算法),主流編程語言普遍已有MD5實現。將數據(如漢字)運算為另一固定長度值,是雜湊演算法的基礎原理,MD5的前身有MD2、MD3 ...
  • 我們今天簡要介紹RS指令在狀態機中怎麼處理的。有些設備按下停止按鈕後,沒有馬上停止,而是到原點後才停止,那麼這種情況在狀態機中如何表示呢?我們以案例說明之,下麵是我們的控制描述。控制描述小車從左位開始,從左向右行使,到達右位後停5秒,然後從右向左運行,到達左位後停3s,繼續向右運行。當按下停止按鈕後... ...
  • 首先有一個html頁面,頁面有一個鏈接,點擊鏈接彈出文件下載/保存(類似迅雷下載鏈接) <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title> ...
  • 在使用Html+ashx處理文件上傳時,遇到上傳文件超過4M的問題,首先HTML代碼如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <titl ...
  • Visual Studio提示“無法啟動IIS Express Web伺服器”的解決方法 有時,在使用Visual Studio運行ASP.NET項目時,會提示“無法啟動IIS Express Web伺服器”,無法運行,如圖: 這一般出現在重裝系統之後,或者項目是從別的電腦上複製過來的。解決方法就是 ...
  • 在Tomcat中主要有以下幾種類載入器:(圖片來自網路) tomcat啟動時,會創建幾種類載入器: 1 Bootstrap 引導類載入器 載入JVM啟動所需的類,以及標準擴展類,位於jre/lib/ext下。 2 System 系統類載入器 載入tomcat啟動的類,比如bootstrap.jar, ...
  • 前言 本文主要是筆者小結 WWDC2017 中 "《What's New in Swift》" 的 Session ,其中也摻雜了些《What’s New in Foundation》,僅作記錄。 下麵步入主題。 私有訪問控制("Private" Access Control) "SE 0169" ...
  • 這張圖我相信基本上對JVM有點接觸的都應該很熟悉,可以說這是JVM入門的第一課。其中的“堆”和“虛擬機棧(棧)”更是耳熟能詳。下麵將圍繞這張圖對JVM的運行時數據區做一個簡單介紹。 程式計數器(Program Counter Register) 這和電腦操作系統中的程式計數器類似,在電腦操作系統 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...