資訊猿

有點東西

技術提供:Blogger.
  • 首頁
  • 旅遊
  • 開箱
  • 教學
  • 筆記
  • 住宿
顯示具有 筆記 標籤的文章。 顯示所有文章
#include <iostream>

using namespace std;

struct Node
{
    int data;
    Node* next;
};
//typedef struct Node* LinkList;

Node* insert(Node* ptr, Node* &specNode, int data)
{
    Node *tmp = new Node;
    tmp->data = data;
    tmp->next = NULL;
            
    if(specNode == NULL)   // 初始插入
    {
        ptr = tmp;
        specNode = ptr;
    }
    else
    {
        if(specNode->next == NULL)  // 尾部插入
        {
            specNode->next = tmp;
            specNode = specNode->next;
        }
        else   // 中間插入
        {
            tmp->next = specNode->next;
            specNode->next = tmp;
        }
    }
    return ptr;
}

Node* deleteNode(Node* ptr, Node* specNode)
{
    Node *curr = ptr;
    if(curr == specNode)   // 頭節點刪除
    {
        ptr = specNode->next;
        specNode->next = NULL;
        delete specNode;
    }
    else                   // 非頭節點刪除
    {
        while(curr)
        {
            if(curr->next == specNode)
            {
                curr->next = specNode->next;
                specNode->next = NULL;
                delete specNode;
            }
            curr = curr->next;
        }
    }
    
    return ptr;
}

Node* inverse(Node* ptr)
{
   Node *first, *tmp ;
   first = NULL;  // 新head
   tmp = ptr;     // 跟著舊head走
   while(ptr != NULL)
   {
      ptr = ptr->next;
      tmp->next = first;
      first = tmp;
      tmp = ptr;
   }
   return first;
}

void display(Node* ptr)
{
    while(ptr != NULL)
    {
        cout << ptr->data <<endl;
        ptr = ptr->next;
    }
}

int main()
{
   Node *first = NULL, *curr = NULL, *test = NULL;
   for(int i=0; i<10; i++)
   {
       first = insert(first, curr, i);
       if(i==5)
       {
           test = curr;
       }
   }
   
   insert(first, test, 20);
   deleteNode(first, test->next);
   first = inverse(first);
   display(first);
   return 0;
}
Share on:
  • extern:
    • 可以聲明變數會在其它的位置被定義,這個位置可能是在同一份文件之中,或是在其它文件之中
    • 不能在使用extern時同時指定其值,必須先聲明extern找到變數,再重新指定其值
  • extern "C" :
    • 在C++ 裡面要用到C的函式會用到
    • 是C++特有的組合關鍵字,在C裡並沒有這個的組合,原因是C++有複載(overloading)
    • 這個字組就是請C++不要自己又偷天換日,請它保留原名
    • extern "C" bar(int i, int j); 編譯器就不會把bar變成_bar_double_double。
    • extern "C"
    • {
    • #include "C_LIB.h"  //C_LIB 是C語言所製告出來的。
    • }
  • template : 
    • 函式範本(Function template)又稱「通用函式」(Generic function),它可以適用於不同資料型態的參數列,但實作內容相同的函式
    • template <typename X> , template <class X> 
      • 須把實作程式碼寫在.h檔裡
      • 或include "xxx.cpp"
      • 或使用export
  • virtual:
    • 只要基類在定義成員函數時已經聲明了virtue關鍵字,在派生類實現的時候覆蓋該函數時,virtue關鍵字可加可不加,不影響多型實現
  • 每個pointer的大小都為4 bytes,不論型態為何
  • C的結構體和C++結構體的區別
    • C的結構體是沒有構造函數、析構函數、和this指針的。
    • C的結構體對內部成員變量的訪問權限只能是public
    • C語言的結構體是不可以繼承的,C++的結構體是可以從其他的結構體或者類繼承過來的
  • class 的 const成員不能在建構式中給初始值
    • 須使用 CBook() :m_price(8.8) { }  給初始值
  • explicit :
    • 禁止構造函數自動進行隱式類型轉換
    • 例如CBook中只有一個參數m_price,在構建對像時可以使用CBook c = 9.8這樣的隱式轉換,使用explicit防止這種轉換發生
  • static :
    • C:對local變數宣告成static,記憶體不會歸還,延用著上次的值
    • C:對global變數或函式,可視範圍僅限此cpp檔(連結時不會去找),不同cpp可用同名函式
    • 代表他是「與 class 相關連」,而不是「與物件相關連」。他獨立配置記憶體,獨立於 class 的任何物件而存在,這個 class 產生的所有物件共用使同一個 static member variable,甚至不需要有物件也能夠被使用
    • static member function 只能存取 static member variable
    • Static Class,當整個程式跑完,才會結束、執行Destructor。
  • Call Back Function
    • 簡單的說,如果你使用了某個function,那麼你就是『call』了一個function。如果系統或是函式是要求你給一個function pointer,這個function pointer指到一個實際的函式(多半這個函式是你自己寫的)。然後它會在適當的時間呼叫此function,則此function就是所謂的 callback function。因為這個function是被『callback』了。
  • 指標概念 :
    • 指標空間釋放(delete)後,指標變數仍會記錄其位址,為避免誤用,釋放後應指向NULL
    • 動態配置一個2×3的陣列
    • int** ppInt;
      ppInt = new int*[2];
      for(int i = 0; i < 2; i++)
          ppInt[i] = new int[3];
      
      for(int i = 0; i < 2; i++)
          delete [ ] ppInt[i];
      delete [ ] ppInt;
      
      
    • 有new就要有delete,若在副程式new又需回傳指標,則需在主程式接收指標後delete該空間,但不建議在副程式new記憶體且回傳指標,因若封裝給別人使用,別人不知道副程式裡面有new而沒delete掉,就會造成memory leak
  • 當表達式中存在有符號類型和無符號類型時所有的操作數都自動轉換為無符號類型(unsigned)。因此-20變成了一個非常大的正整數
  • volatile :
    • volatile變數代表其所儲存的內容會不定時地被改變,宣告volatile變數用來告訴編譯器 (Compiler) 不要對該變數做任何最佳化操作,凡牽涉讀取該volatile變數的操作,保證會到該變數的實體位址讀取,而不會讀取CPU暫存器的內容,可確保每次讀取的內容都是最新的
  • mutable
    • 加mutable关键字的成员变量,修饰为const的成员函数就可以修改它了。



    • malloc()、free()、calloc() 與 realloc()
      • int *arr1 = malloc(1000 * sizeof(int));   //說明陣列動態配置的方式
      • int *arr1 = calloc(1000, sizeof(int));    //宣告空間配置
      • free(arr1);
      • int *arr2 = realloc(arr1, sizeof(int) * size * 2);
      • arr1與arr2的位址相同並不保證,realloc ()會需要複製資料來改變記憶體的大小,若原位址有足夠的空間,則使用原位址調整記憶體的大小,若空間不足,則重新尋找足夠的空間來進行配置,在這個情況下,realloc()前舊位址的空間會被釋放掉,因此,您必 須使用realloc()所傳回的新位址,而不該使用舊位址,若realloc()失敗,則傳回空指標(null)
    • const int* p 和 int* const q 兩者之差別:
      • 前指標指的內容不可變動,後指標不可變動
      • void dp()const; \\我不會更改成員
      • const int* op() const{return &data;}  //回傳const參考 保證不會更改
      • 3的倍數:所有的偶数位和奇数位出现1的次数 的差為3的倍數(遞迴)
        • 32-bit machine用C語言對位址 0x00005000 的第三個bit設成0,第五個bit設成1
        • int i = 0x00005000;
          i = i & 0x00001000;
        • 寫出一個Macro求出兩數之最大值:
          • #define Max(x, y) ((x)>=(y)? (x): (y))
        • 給予10個任意整數,輸出其最小值、最大值、平均值
        • int Max = a[0], Min = a[0], Avg = 0; 
              for(int i = 0 ; i < 10 ; i++)
              {
                  if(Min > a[i])
                      Min = a[i];
                  if(Max < a[i])
                      Max = a[i];
                  Avg += a[i];
              }
             cout << Min << Max << static_cast<float>(Avg)/10 << endl;
        • 寫出一個字串拷貝程式: void StrCpy(char* dst , char* src)
          • for(; *src != '\0', *dst = *src; dst++, src++)
        • interrupt service routine 之錯誤
        • __interrupt double isr(double r)
          {
           double area = PI*r*r ;
           printf("%f\n",area) ;
           return area ;
          }
          • ISR不能有返回值(不知道給誰)
          • ISR不能傳遞參數(不知道誰呼叫)
          • 浮點運算和pintf有重入問題
          • ISR應短而高效
        • 整數轉換字串
        • char* s;
          sprintf(s, "%d", i);
        • 寫出一個程式若輸入為 12345678 , 則返回值為 56781234
          • DWORD  fun(DWORD num)
          • typedef unsigned long DWORD;
            DWORD fun(DWORD num)
            {
                DWORD h, l;
                h = num << 16;
                l = num >> 16;
                return h ^ l;
            }
            

            • 設定一個絕對位址為0x67a9的整數型變數的值為0xaa55
            • int *ptr;
              ptr = (int *)0x67a9;
              *ptr = 0xaa55;
              
              • 重載問題
              • class E
                {
                public:
                    int test(int *i)
                    {
                        cout << "1" <<endl;
                    }
                    int test(int &i)
                    {
                        cout << "2" <<endl;
                    }
                    int test(const int &i)
                    {
                        cout << "3" <<endl;
                    }
                    /*int test(int i)
                    {
                        cout << "4" <<endl;
                    }*/
                };
                
                int main()
                {
                   int *i = new int(10);    // 1
                   int a = 10;              // 2 4 無法分別 只能留一種
                   const int b = 10;        // 3
                    
                   E t;
                   t.test(i);
                   t.test(a);
                   t.test(b);
                   
                   return 0;
                }
              • 判斷2的次方
                • X&(X-1) == 0
              • 單向LinkList操作
                • http://leeweiyutoro.blogspot.tw/2014/12/cc-linklist.html

              • int main()
                {
                         int a[5][2] = {0,1,2,3,4,5,6,7,8,9};
                        
                         int *p = a[0];
                         int (*p2)[2] = &a[1];
                         ++p;
                         ++p2;
                        
                         printf("%d\n",*p); //1 p 是整型指針,初始指向元素0,加1指向1
                         printf("%d\n",**p2); //4 p2是含2個元素的數組指針,初始指向元素2,該指針加1是向後移動2個數據,所以指向4
                         printf("%d \n",p2[1][2]); //如何解讀? 見下解讀。 
                         return 0;
                }

              • function pointer array 代替if else
              • #include <iostream>
                #include <stdio.h>
                using namespace std;
                
                void run() {  
                    printf("start\r\n");  
                }  
                  
                void stop() {  
                    printf("stop\r\n");  
                }  
                  
                void exit() {  
                    printf("exit\r\n");  
                }  
                
                static void (*command[])(void) = {run, stop, exit};  
                  
                int OnStateChange(int state) {  
                         
                    if (state >= 3) {   
                        printf("Wrong state!\n");  
                        return false;  
                    }  
                  
                    command[state]();  
                    return 0;  
                }  
                
                int main()
                {
                   OnStateChange(0); 
                   
                   return 0;
                }

                • int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
                  int *p = &(a + 1)[3];
                  printf("%d\n", *p);
                  • 輸出 5 ,因為a+1指向a的第二個元素,[3]表示再向後移動3個元素
                  • a+1是跳一個int的大小(a想成指標)
                  • &a+1是跳一整個array的大小
                • int  var[3] = {10, 100, 200};
                  • var 是 constant  不能用 var++  只能 *(var+2) = 500;
                Share on:
                開發 Line 機器人最重要的就是寫 web hook
                那 webhook 就必須找個 server 來存放
                可以免費放 webhook 的有 MS Azure, Amazon, Google Cloud... 等服務商
                這些都要另外註冊帳號、設定 server 、可能還有期限流量等限制

                用 google script 不須經過這些設定
                就能直接編寫接收 line 訊息並回傳的機器人

                以下範例為取得聊天室 ID 或 UserID
                只要取得這些 ID 就能發送 push 訊息到這些 ID 的聊天視窗了

                function doPost(e) {
                  var urlReply = 'https://api.line.me/v2/bot/message/reply';
                  var urlPush = 'https://api.line.me/v2/bot/message/push';
                  var myGroup = 'XXXXXXX';         // push 訊息到這個 ID
                  var send_message = 'doPost message';
                  var strSourceType = "";
                  var strNewRoomID = "";
                  var strNewGroupID = "";
                  var strNewUserID = "";
                  
                  var recieveData= JSON.parse(e.postData.contents);
                  if (recieveData.events[0].type == "join")
                  {
                    if ( recieveData.events[0].source.type == "room" )
                    {
                      strSourceType = "room";
                      strNewRoomID = recieveData.events[0].source.roomId;
                      strNewUserID = recieveData.events[0].source.userId;
                    }
                    else if ( recieveData.events[0].source.type == "group" )
                    {
                      strSourceType = "group";
                      strNewGroupID = recieveData.events[0].source.groupId;
                      strNewUserID = recieveData.events[0].source.userId;
                    }
                    else if ( recieveData.events[0].source.type == "user" )
                    {
                      strSourceType = "user";
                      strNewUserID = recieveData.events[0].source.userId;
                    }
                    
                    send_message = "SourceType:" + strSourceType;
                    send_message = send_message + " RoomID:" + strNewRoomID;
                    send_message = send_message + " GroupID:" + strNewGroupID;
                    send_message = send_message + " UserID:" + strNewUserID;
                    UrlFetchApp.fetch(urlPush, {
                      'headers': {
                        'Content-Type': 'application/json; charset=UTF-8',
                        'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
                      },
                      'method': 'post',
                      'payload': JSON.stringify({
                        'to': myGroup,
                        'messages': [{
                          'type': 'text',
                          'text': send_message,
                        }],
                      }),
                    });
                  }
                }
                

                第一次要取得當下聊天視窗的ID
                可以用reply的方式回應到當下的視窗
                reply不需要輸入userID或groupID就能回傳到當下聊天視窗的ID

                UrlFetchApp.fetch(urlReply, {
                      'headers': {
                        'Content-Type': 'application/json; charset=UTF-8',
                        'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
                      },
                      'method': 'post',
                      'payload': JSON.stringify({
                        'messages': [{
                          'type': 'text',
                          'text': send_message,
                        }],
                      }),
                    });
                
                Share on:
                • ← 較舊文章
                • This blog is to provide you with useful information and share my personal experience.
                • Share. Learning. Thinking.
                140x140

                INFO APE

                Founder of the website
                Labels
                • 2018日本合掌遊
                • C++
                • 住宿
                • 教學
                • 筆記
                • 英法義自助
                • 開箱
                最新文章