Sunday, October 11, 2020

函式指標的使用,以及使用函式指標的好處

函式指標是指向函式的指標變數。

程式在編譯時,每一個函式都有一個入口地址,該入口地址就是函式指標所指向的地址。

1. 函式指標的宣告

bool (*pf)(int, int);

//pf指向一個函式,該函式的引數是兩個int,返回值是 bool 型別

2. 函式指標的初始化

//例如有這樣一個函式:bool cmp(int a, int b);

pf = cmp//注意 cmp 型態返回值應與宣告的的函式指標的型別匹配

3. 呼叫函式指標

bool b = pf(3,5);

等價於直接呼叫:bool b = cmp(3,5);

函式指標有兩個方面的應用:

1. 把指標函式當作形參傳遞給某些具有一定通用功能的模組。並封裝成介面來提高程式碼的靈活性和後期維護的便捷性

example:

void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));

1. 待排序陣列首地址
2. 陣列中待排序元素數量
3. 各元素的佔用空間大小
4.  指向函式的指標,用於確定排序的規則 (可提供不同的排序法)

歸納為:便於分層設計、利於系統抽象、降低耦合度以及使介面與實現分開。

這裡通過比較一個比較 low 的氣泡排序來說明一下 qsort 內部函式指標的實現機制:

#include<iostream>
using namespace std;
void sort(int arr[], int size, bool(*cmp)(int,int));
bool up(int a, int b);
bool down(int a, int b);
int main()
{
    int arr[10];
    for (int i = 0;i < 10;++i)
        cin >> arr[i];

    sort(arr, 10,down);

    for (int i = 0;i < 10;++i)
        cout << arr[i] << " ";
    return 0;
}
void sort(int arr[],int size,bool(*cmp)(int,int))//簡單氣泡排序
{
    int temp;
    for (int i = 0;i < size-1; ++i)
    {
        for (int j = i;j < size-1;++j)
        {
            if (cmp(arr[i], arr[j + 1]))
            {
                temp = arr[i];
                arr[i] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
bool up(int a, int b)
{
    if (a > b)
        return 1;
    else
        return 0;
}
bool down(int a, int b)
{
    if (a > b)
        return 0;
    else
        return 1;
}
2. 有些地方必須使用函式函式指標才能完成給定的任務,如linux系統中的非同步訊號中斷處理,當發生某一觸發訊號時,需要呼叫相應的處理函式,此時需要使用函式指標來實現。

void (*signal(int signum,void(* handler)(int)))(int); 

引數一為訊號條件,第二個引數為一個函式指標,它所指向的函式需要一個整型引數,無返回值。
該函式的返回值也是一個函式指標,返回的指標所指向的函式有一個整型引數(一般不用)

if-else條件改成以函式指標陣列(array of function pointer)的方式改寫

#include "stdio.h"

#include "stdlib.h"

int plus(int a, int b) { return a + b; }
int minus(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divided(int a, int b) { return a / b; }
int main()
{
 int a, c;
 char b;
 printf("key a Function \nEX: 1 + 1\n");
 scanf("%i %c %i", &a, &b, &c);

 if (b == '+')
  printf("%d %c %d = %d\n", a, b, c, plus(a, c));
 else if (b == '-')
  printf("%d %c %d = %d\n", a, b, c, minus(a, c));
 else if (b == '*')
  printf("%d %c %d = %d\n", a, b, c, multiply(a, c));
 else if (b == '/')
  printf("%d %c %d = %d\n", a, b, c, divided(a, c));
}

 =========================================================================

#include"stdio.h"

int plus(int a, int b){ return a+b; }
int minus(int a, int b){ return a-b; }
int multiply(int a, int b){ return a*b; }
int divided(int a, int b){ return a/b; }

int main(){
    int a, c;
    char b;
    scanf("%d %c %d", &a, &b, &c);
    
    int (*cmd[])(int a, int c) = {multiply, plus, NULL, minus, NULL, divided};

    printf("%d\n",cmd[b-42](a,c));  // '*' ASCII = 42(0x2a)  ,'+' ASCII = 43 (0x2b), '-' ASCII = 45, '/' ASCII = 47    

    return 0;
}

Thursday, October 8, 2020

repo index

error: Your local changes to the following files would be overwritten by checkout:
    Android.mk
    extendedcommands.c
    flashutils/Android.mk
    flashutils/flashutils.c
    flashutils/flashutils.h
    mounts.c
    mounts.h
    nandroid.c
    roots.c
Please, commit your changes or stash them before you can switch branches.
Aborting
error: Your local changes to the following files would be overwritten by checkout:
    encore.mk
    init.encore.rc
Please, commit your changes or stash them before you can switch branches.
Aborting
<few more errors like this.........>
error: bootable/recovery/: CyanogenMod/android_bootable_recovery checkout 50822991460cbee65757e9de12b29e39238d6386 
error: device/bn/encore/: CyanogenMod/android_device_bn_encore checkout f6586ab41f0e3f5acfa16b43f9b17008e9bb0524 


解法:丢弃修改

repo forall -c git reset --hard HEAD


How switch to special tag?

repo forall -c "git checkout <special tag>"


repo sync -c -n -j4 && repo sync -c -l -j 16 

前面是抓code, 後面是長code


repo 打 tag

repo forall -c 'git tag spectralink_sprint_8'

repo forall -c 'git push origin --tags'

切换到另一个分支

repo forall -c git checkout your_branch

删除分支

repo forall -c git branch -D 分支名称


[git]repo、branch和tag取名建議和注意事項 - 怎麼取名比較不會有問題

Tuesday, October 6, 2020

Android Logcat

 Android studio 过滤log中指定字符(不显示包含指定字符的log)

^(?!.*(你要过滤掉的字符)).*$

*log中包含got 或Activity 的log将不显示在控制台。

^(?!.*(got|Activity)).*$


只显示指定字符的log

^(.*(10:30|10:33)).*$

Logcat


採用grep正則表示式過濾

adb logcat | grep -iE "Audio3DSettings|setParameters|setAudio3DState"


在同時輸出到螢幕和檔案 tee

adb logcat | grep -E '^[VDE]/(TAG1|TAG2)' | tee my.log


可以看出 tag 是一行開頭的第三個字元開始

adb logcat | grep "^..MyApp"


僅顯示 Error 級別 tag 為 MyApp 的輸出

adb logcat | grep "^E.MyApp"


要匹配 tag 為 MyApp 和 MyActivity 的輸出

adb logcat | grep "^..MyApp\|^..MyActivity"

adb logcat | grep -E "^..MyApp|^..MyActivity"  #使用 egrep 無須轉義符


過濾 tag 為 MyApp 和 MyActivity 的輸出

adb logcat | grep -v "^..MyApp\|^..MyActivity" 

adb logcat | grep -vE "^..MyApp|^..MyActivity"  #使用 egrep 無須轉義符

logcat | grep -vE "BluetoothAdapter|chatty| BluetoothManagerService| *bluetooth* | *Bluetooth*|bluetoot|bt_*"

顯示同一個程序的所有輸出

#!/bin/bash

packageName=$1 

pid=`adb shell ps | grep $packageName | awk ‘{print $2}’` 

adb logcat | grep –color=auto $pid


從當前開始顯示

adb logcat -c && adb logcat

logcat | grep -e Controller -e StateDvrPlayback

grep 指令使用 or 及 and 查兩個條件以上

Saturday, October 3, 2020

c 考古題

1.  如果想描繪下圖之鑽石形狀

     *     
    ***    
   *****   
  *******  
 ********* 
***********
 ********* 
  *******  
   *****   
    ***    
     *     

請參考以下程式碼

#include <stdio.h>

int main(int argc, const char * argv[])
{
    for(int i = -5; i <= 5; i++)
    {
        for(int j = -5; j <= 5; j++)
        {
            if(i <= j + 5 && i <= -j + 5 && i >= -j - 5 && i >= j - 5)
                printf("*");
            else
                printf(" ");
        }
        printf("\n");
    }
}

2. 如果想描繪下圖之三角型, 星號由一到十遞增

         *
        **
       ***
      ****
     *****
    ******
   *******
  ********
 *********
**********

請參考以下程式碼

1. 第一個迴圈代表執行十次

2. 第二個內迴圈也執行十次, 但裡頭多加一個判斷式

    因這三角形星號是由右邊往左列印, 因此下了 j <= 10 - i

    因此i == 1時印出九個空格, 條件不滿足時才列印出星號

3. 跳出內迴圈後印出換行符號    

#include <stdio.h>

int main(int argc, const char * argv[])
{
    for(int i = 1; i <= 10; i++)
    {
        for(int j = 1; j <= 10; j++)
        {
            if(j <= 10 - i)
                printf(" ");
            else
                printf("*");
        }
        printf("\n");
    }
}

3. 若想描繪下圖之三角型, 由上而下為一顆, 兩顆星號, 以此類推到十顆

*
**
***
****
*****
******
*******
********
*********
**********

請參考下列程式碼:

1. 第一個for迴圈代表會執行十次

2. 第二個for迴圈代表會印出星號, 印出的次數會以變數i為準

3. 若j <= i條件不成立, 則內迴圈執行結束並印出換行符號

#include <stdio.h>

int main(int argc, const char * argv[])
{
    for(int i = 1; i <= 10; i++)
    {
        for(int j = 1; j <= i; j++)
        {
            printf("*");
        }
        printf("\n");
    }
}

 

4. 

n8n index

 【n8n免費本地端部署】Windows版|程式安裝x指令大補帖  【一鍵安裝 n8n】圖文教學,獲得無限額度自動化工具&限時免費升級企業版功能