2016年8月31日 星期三

指標微小而重要的常識

指標微小而重要的常識

tags:C++

delete 與 delete [] 差異

兩者都會呼叫解構函式,差別在於
後者只會呼叫開頭指標的解構函式
簡單來說今天你配置了arr[n]的動態陣列
如果你僅使用 delete 那只會解構 arr[0]
後面全部都不會被解到,可怕的是
這並不意味不能編譯與執行。
為了避免這種情況,記得養好習慣
聽起來很複雜,用一句話概括
方括配方括

這裡如果還不夠明白,簡單測試一下就能馬上了解了
#include <iostream>
class cls{
public:
    cls(){ std::cout << "constructor" << std::endl; }
    ~cls(){ std::cout << "destructor" << std::endl; }
};
int main(){
    cls* p = new cls[5];
    delete [] p;
    return 0;
}

釋放的指標最好手動指向空指標

上面我們可以知道 new[] 必須搭配 delete []
這裡還有一個小問題,你可以嘗試著把上方的代碼
印出釋放後的指標,你會發現指標沒有指向 0
這不是太大問題,但是如果造成問題了(肯定會有的
只是用到機率不大),應該不容易被找到問題點
養成習慣最好在釋放後手動指向空指標
空指標這裡簡單的敘述什麼該用什麼
  • C 使用 NULL
  • C++ 使用 0
  • c++11 使用 nullptr
千萬不要因為看起來不重要,且實際實際執行
時確實無法直接看出差別,就忽視了或偷懶

如果你不想 delete 那麼多

乾脆算出長度宣告成一維陣列
下標仍然可以使用,直接加上就好[][]
void* new2d(int h, int w, int size){
    register int i;
    void **p;
    p = (void**)new char[h*sizeof(void*) + h*w*size];
    for(i = 0; i < h; i++)
        p[i] = ((char *)(p + h)) + i*w*size; 
    return p;
}
因此就可以用這 function 動態建立二維陣列
data = (int **)new2d(data_height, data_width, sizeof(int));

可以把他整合到Macro
在程式前頭增加
#define NEW2D(H, W, TYPE) (TYPE **)new2d(H, W, sizeof(TYPE))
便可簡化剛剛動態配置二維陣列寫法
data = NEW2D(data_height, data_width, int);

參考資料

  1. [問題] 指標 直接存取與使用下標存取 差異
    https://www.ptt.cc/bbs/C_and_CPP/M.1472632682.A.DE7.html
  2. 關於指標的new、delete、NULL的觀念問題
    http://www.programmer-club.com.tw/showSameTitleN/c/37427.html
  3. Re: [心得] 空指標常數(null pointer constant)
    https://www.ptt.cc/bbs/C_and_CPP/M.1461824349.A.B47.html

2016年8月29日 星期一

Git for windwos [修改 預設 工作 目錄] 與 [自訂命令]

Git for windwos
  1. 如果你的工作目錄固定,又或是放在D槽,修改預設目錄可以省下不少重複動作
  2. 有一些比較長的指令也可以利用 alias 縮短成比較簡單的

修改初始位置

到這個目錄底下修改 bash.bashrc
C:\Program Files\Git\etc
必須使用管理員權限才能修改
或者先複製到桌面修改完畢覆蓋回去
在最底下加入自己想要的路徑
(我是指定到OneDrive內)
cd OneDrive\\KUAS-Hw
注意斜線是兩條

alias

一樣在這個文件最底下加入你要的命令
alias add=’git add -i’
我是把 git add -i 改成 add
所以我只要輸入add就可以加入檔案了

2016年8月27日 星期六

指標的基本用法

指標

基本概念
  • 符號意義
副程式
  • 為何副程式必須導入指標
  • 副程式引入處指標與陣列不同
  • 如何從副程式得到指標長度
  • 間接定址與直接定址
  • 為何需要指標的指標
 指標類型
  • 指標的指標
  • 結構指標
  • 虛無指標
下周分享內容:如何有效率的編程

基本概念

符號意義

記住兩句話 &找地址 *找數值  
int i=1 程式初始化配置記憶體
給變數i使用並在裡面儲存數值1
可以透過 &i 查找記憶體地址
int* p=&i 創建一個指標,並告知
編譯器這個用來儲存儲存整數,再來存入
i 的地址
可以透過 *i 查找記憶體地址內的數值
關於指標的創建,請記住這句話
告知編譯器這個用來儲存儲存整數
後續會繼續討論,這裡先討論兩個區別
int* iint *i 有什麼區別呢
在編譯器內他們是等價的,但建議使用前者
的方式宣告,更容易閱讀,可以想像
把他們當成另一個型態 int*
這樣更容易閱讀對吧XDD
那什麼時候才需要用到把星號放到後面呢?
int* i, j; 你覺得後面的j是什麼型態呢
直覺得˙會把它看成 int* 型態但其實他們是
等價於 int* i; int j
這時候我會建議你都把他們放後面吧
int *i, *j; or int *i ,j;
這樣就更容易閱讀了

副程式

為何副程式必須導入指標

有了前者得概念,現在來出一到小題
如何使用副程式修改變數
簡單的來形容主程式內有一個變數
我要呼叫一個副程式修改i的數值
int i=0;
modify();
如何實做呢 https://goo.gl/2EMGo3

副程式引入處指標與陣列不同

fun(int* arr);

fun(int arr[4]);
用途上來看最主要大概差異在
前者沒有把數字定死,想傳幾個都可以傳
即便是後者,你傳入一個長度是5的陣列能然能取到
第5個的數值,這純粹只是運氣好,第5個的數值
只是因為宣告時記憶體是連續的,運氣好可以讀到
程式如果複雜了,並不能保證他不會修改

如何從副程式得到指標長度

通常來說都會在下標的第[0]個儲存長度
這可以節省運算時間,也讓你更好操作
C++可以透過樣板取得取得長度
template<size_t N>
void arr_len(int (&arr)[N]) {
    std::cout << "sizeof = " << sizeof(arr) << " / ";        
    std::cout << sizeof(arr[0]) << std::endl;
    std::cout << "len = arr[" << N << "]" << std::endl;
}
樣板會干擾到拆分程式,還是建議採用前者

間接定址與直接定址

假設有一個二微陣列是 [2][2]
那麼在記憶體上第三個是 [1][0]
輸入 [1][0] 在操作上必須找兩次,
先找到[0]的地址再去查找地址的數值
速度上會略低,如果宣告成一微陣列
自己手動算出[2][2]是第3個
效率上會來的好一些,在操作上也較容易

為何需要指標的指標

  1. 存取動態二維陣列
  2. 副程式拆解上的需求
這可能有點難形容,兩者其實
也差不都在形容同一件事情
直接看代碼或許會比較好理解
核心代碼
imch imgraw::cubicInterpolate (imch* p, double x) {
    double temp = (double)(p[1] + 0.5 * 
        x*(p[2] - p[0] +x*(2.0*p[0] - 5.0*p[1] + 4.0*p[2] - 
            p[3] + x*(3.0*(p[1] - p[2]) + p[3] - p[0]))));
    return (imch)temp;
}
用來控制核心代碼的驅動
imch imgraw::bicubicInterpolate (imch** p, double y, double x) {
    imch* arr = new imch[4];
    for (int i = 0; i < 4; ++i)
        arr[i] = cubicInterpolate(p[i], x);
    return cubicInterpolate(arr, y);
}
如果沒有將核心代碼拆分出來,核心代碼必須重複5次

指標的指標

動態二維陣列的應用
// 創建
int** ptr = new int* [2];
for (int i = 0; i < 2; ++i)
    ptr[i] = new int [2];

// 釋放
for (int i = 0; i < 2; ++i)
    delete [] ptr[i];
delete [] ptr;

結構指標

結構
struct node{
    int i;
};
結構指標要用->去指向
node a, *b;
b = &a;
a.i = 1;
cout << b->i << endl;
return 0;

虛無指標

這應該很少會用到,但如果你要把程式寫好
寫得足夠嚴謹,就必須得用他,
很多底層的代碼,都是這樣定義的
//接收不同型態的資料
void pri_int(void* data){
    int temp=(int)*data;
    cout << "temp=" << temp << endl;
}
這個副程式將可接受各種型態的指標
最終cast成整數的樣貌,印出

2016年8月26日 星期五

Youtube 自訂 播放速度 大於 > 2

內建的播放速度只有到2而已,其實可以自由調整至更快的
  1. Chrome 按下F12開啟命令視窗
  2. 輸入 document.getElementsByTagName("video") [0].playbackRate = 5
最後面的 5 是播放倍數,可以自由設定

2016年8月24日 星期三

Win7 8 10 如何設定 資料夾內 所有子資料夾 變成超大圖示 [批次更改圖示顯示方式]

請注意不要漏掉任何步驟了,改了整個Windwos都會變了
可別整台變成你不想要的形式了,到時候一定很乾XDD
有的時候你可能想要修改整個資料夾,包含資夾內的子資料夾
一口氣全部修改成超大圖示,卻不曉得該怎麼辦
搜了一下網路,其實沒什麼資料 (我大概是一年前蒐的)
只好一個一個資料夾慢慢改QQ
改成大圖示還好,有預設值可以套用,超大圖示就沒了
這裡會介紹如何詳細的批次修改系統內的顯示方式
主要兩個概念
  • 套用預設規則
  • 更改系統預設規則

套用預設規則

先說說如何批次套用預設的規則
這樣就會全部都變成大圖示摟,如打打勾套用到子資料夾
裡面有包含的資料夾通通都會變成大圖示了

更改系統預設規則

首先非常重要的一點
注意請關掉所有資料夾留一個就好
開啟你的使用者文件(或貼上我提供的位置)
%USERPROFILE% \Pictures
將該位置改成大圖示,並更動預設檢視數值
之後再執行上一步 套用預設規則
套用成圖片的預設規則(剛剛改的)
就會發現全部都變成超大圖示了
改好之後可以直接從上面修改成大圖示
或是詳細清單的方式,增加最外層資料夾
一次可瀏覽的項目,不會影響子資料夾
為什麼要反過來寫是先讓你熟悉一下
而且多數可能只會用到上一步XDD

細節

  1. 套用時會針對當前顯示最上層的資料夾套用規則
    所以才跟你說要關乾淨XD
    如果你有一個是普通型態的資料夾

    (幾乎所有的資料夾都會是一般項目
    除非你放了一堆影片進去,他自動轉態成影片)
    這時候如果你為了方便將一般項目改成大圖示
    沒選好你這一套用,可能整個C曹都變成大圖示了
  2. 套用規則只能有5個

    也就只有這麼5個能用而已啦XD
    沒辦法自己在多設定了
    我個人是把圖片改成超大圖示
    這樣比較不會干擾到其他地方

嗯…這一篇其實是用來高效率挑 (( 誤
試著在D槽的右上角輸入底下字串試試看
((*cari* OR *1pon*) AND *.mp4) OR (~<n??? OR ~<n????) AND (*.mp4 OR *.wmv)
這種搜索方式非常實用,對於把電腦當圖書館的人來說
看看你的電腦都搜出了些什麼XD
自己在替換成適合的相關字符
一樣用 OR (你的規則) 就可以了
注意 OR 是大寫且前後都要有空格
最後再改成適當的方式顯示
這裡的顯示方式會儲存,記得改回來相關性
不然真要找檔案的時候,會不太好找XDD

2016年8月22日 星期一

Windwos10-1607 升級的過程與注意事項 [黑屏 黑桌 剩滑鼠]

前一陣子升級時因為ubuntu裝壞了,
乾脆把他還原了,今天把他升級回來
遇到了一些可能是問題的問題,記錄一下
  • 25% 的時候會重開
  • 50% 的時候會黑屏剩滑鼠還能動
  • 75% 的時候再次重啟
  • 更新後的第一次啟動盡可能不要使用在重啟一次
我的C槽使用量是83G,其中包含了24G的old檔案
一共耗費了30分鐘升級,硬碟是 Savage240G

黑屏

值得一提的是 50% 重啟時非常可怕,黑屏了將近10分鐘
而且滑鼠還能動,怎麼想都會覺得是壞掉了
我有2次經, 我在最後的時候有動一下滑鼠,並按CTRL幾下
然後就重啟了有點神奇,這已經是第2次經驗了
雖然沒有根據,不過如果你也卡了很久,試著動滑鼠與CTRL

第一次進桌面

第一次進桌面的時候,我不曉得是設定還沒好,或是怎麼樣
重啟之後,本來是藍色的,變成紫色的,之後再重啟就會恢復藍色了
猜測可能有些東西還沒跑完,推薦重啟完畢再使用電腦

已知問題

這次的更新會莫名其妙地拿掉一些驅動,有些裝回來就好了
有些必須要找新版本的,才能安裝了
已知
  • 英特爾的網卡
  • ACER的杜比音效

控制台無法移除 出現 插入磁片

這是這次升級 Win10-1607 的災情之一

狀況

  • 新版本網路驅動安裝到一半出現插入磁片無法安裝
  • 使用舊版本的則是直接出現無法安裝

解決辦法

到控制台移除舊版本,發現無法移除,出現插入磁片
這時候必須找到你原有的舊版本,只能這樣
任何手段非法移除可能會造成無法挽回的下場
解壓縮舊版驅動、搜尋 .msi
這裡其中一個是我們要的,在出現插入磁片實選中其中一個
兩個都試試看吧,我是選中第一個就成功解除安裝了

原因

其實所謂的安裝檔在安裝之後都會在Windows內留一份安裝檔
這其實還蠻站容量的而且他一點用處也沒有XD
只有在移除的時候才會用到,有些深層的清理軟體可以清理掉這些
千萬不要想不開,否則你就無法移除了
這次會造成這種狀況是因為升級Windwos10
因為是新系統所以沒有這個移除套件
好險在安裝包裡頭有,否則我就無法安裝了QQ

Onedrive 同步卡住 永遠跑不完

這問題其實Google的雲端硬碟也會,觸發條件就是重複編輯
比如說你在編寫程式碼,不斷的儲存編譯,很容易就卡住了
處理辦法很簡單
重新啟動Onedrive
重新開機是一個辦法,因為他會重新啟動OneDrive
不過這太耗費時間了,直接關閉又不知道從那兒開回來
這裡提供兩個指令供你開關
::關閉
"%windir%\System32\taskkill.exe" /f /im OneDrive.exe
::開啟
start "" "%localappdata%\Microsoft\OneDrive\onedrive.exe"
Exit
你可以把他打在記事本內,然後按另存新檔
將它儲存成bat,這樣一來需要恢復同步,只要點他兩下就可以了
幫你打包好的懶人包:ResetOnedrive

2016年8月21日 星期日

看似省錢的DIY,在某些時候是更花錢的

DIY 最好是在自己有多餘的情況下,或有十足把握才這麼做
手機前幾天壞了,電池脹得跟氣球一樣,型號是Z1
不能換電池的防水機,背板都被撐開了
我到網上去搜尋了一下,發現電池只要含運$400,還附帶工具
想想先前花了$1000 換電池呢,不過那時候是手機泡水順便的
這或許還比較好多的過去,至少我那時候是這麼想的
現在想想
還好我當初花錢了,很多時後花錢才是買便宜呢

這次買了電池運氣不好,買到了有問題的電池說,排線的位置太尷尬了
位置是剛好無法裝上手機的,可以看看下方的圖說明
於是我的手機就這麼拆著沒得用了,不過這對我沒有任何影響
因為我只是拿來當時鐘看,恩…高級時鐘XDD
說是這麼說,其實這支手機是朋友要來的,螢幕是摔壞的XDD
其實一點價值都沒有了,但是擺在桌面上,當時鐘挺好看的

回到主題上來,如果這支手機是我正在使用的呢?
不能想像呢,至少我會因為這樣好幾天沒手機用了
其實早上我小時候,隱約地就對這種狀況有些熟悉了
我小時候很愛弄電腦,免不了拆拆裝裝,造成不少意外呢
不過小時候對電腦需求沒這麼大,壞了就等個幾天吧
長大之後持續幫人修理電腦,我就有意識到了
無論如何,絕對不能拿自己電腦來測試
這其實可以有很多原因的
  1. 要是沒電腦了,怎麼google呢
  2. 把自己弄壞了(更多時候運氣問題),怎麼讓人信服我會呢
於是我在做一些大膽嘗試的時候,不會動用自己的電腦
好在我的電腦有足夠多,這裡的足夠多不是浪費,也不是有錢阿
當時都在雙核心了,我家裡有的是兩三台 P3 的電腦可以給我玩XDD
免費的有些原因的,就不去討論了
正因為有這些我才能無所旁騖的去實驗,去思考,去修復
才能夠有足夠的專力去專注,如何修復,如何做本來正在做的正事
而不是專注於,怎麼辦壞了,是不是我的錯
是不是不該拆,尤其這種專注是天生的且無法停下

如果我的手機就這麼壞了,當然不是指等電池這事兒
是真有可能有意外的,那時候我肯定會有陰影的
早知道就不要拆了
於是我就此放棄學習與成長了,而且毫無自知
甚至還振振有詞的可以對別人說
就是因為我去拆了才會壞,所以手機千萬不要拆
邏輯嚴謹,毫無錯誤,還是事實擺著呢
這麼想想,這真是太可怕了,一不小心入坑了
可怕的是,到了坑裡頭左顧右盼居然發現
沒想到這兒的人,比坑外的人還多著呢
於是你不覺得,這裡是坑

拆機的部分,等電池來惹弄好了,整理一下會發上來的
問題其實沒想像中大,不至於太難拆或裝不回去

2016年8月13日 星期六

AMD 更換 SSD 注意事項 含 IDE 轉 AHCI 方法

AMD [AM3\2] 更換 SSD 注意事項 含 IDE 轉 AHCI 方法

必要項目

截止到目前為止總算是弄好了,大致拆分以下幾個重點
  1. BIOS切換為AHCI模式
  2. 關閉省電模式
  3. 重新安裝系統(win8.1以上)

其他項目

  • 4K對齊
可能有些人會問,4K對齊呢
這個在重新安裝系統裡面提到

來做一個最有趣的探討吧

  • 轉移IDE驅動的系統碟
話先講前頭,即便這能開機,但很容易出問題
可以拿應急但千萬之後要重新安裝系統。
可以參考 it天空 AHCI轉換的一些文獻

BIOS切換為AHCI模式

到BIOS找一下就有搂,有些板子會有 port4/5 可以模擬 IDE
這個千萬要選as SATA 避免你出來的速度被影響

關閉省電模式

找一下BIOS裡面有省電模式都給他關了吧
最少C1E這個項目一定要關
不過我個人比較推崇從作業系統關閉
電源選項 → 慣用計畫 → 高效能
我自己升級了舊電腦 AMD 飛龍X4 965
發現一直卡頓,有事沒事就給你卡住
後來發現是節能問題。關閉就好了

重新安裝系統(win8.1以上)

建議使用 Win8.1 以上的系統
最好是官方原生的,並做足以下幾項
  1. 使用光碟開機
  2. 刪除所有分割
  3. 重新啟動
  4. 重新分配你要的容量
這裡產生了兩個問題
  1. 4k對齊
  2. SSD網上大家都說不可切割

4K對齊

這其實是XP年代才沒有在對齊的後來
VISTA開始導入NTFS格式
這個問題就已經解決了,
文中有提到,刪除所有分割重新啟動
這就是避免你有沒有對齊在幫你對齊
很難想像吧,網路上大家講得多複雜,居然如此簡單
還有一個,啟用什麼SSD不可重組的標記
這邊告訴你,請你相信為微軟吧XDD
即便沒有重裝,他還是會正常自動標記
不過這邊還是建議重裝,以確保不會出bug

SSD不可切割

可切割的理由

這我具體也沒有去參考學術論文
不過可以從以下幾點證明,至少分割是合理的
  • UEFI 標準下,必須切割EFI分割區
  • 微軟自動幫你切好幾個(微軟不會耍蠢啦)
  • 你不切那1T以上的企業級SSD怎麼辦?
  • 間接承認Liux不能使用SSD?所以伺服器不能使用SSD

實測切割4分區後的速度

或許切割真的會掉速,但並沒有他們說的慢
掉速的部分我這邊測試
以下是我的測速圖與環境
  • i7-4970k
  • ASUS-Z97AR
  • DDR3-2400
  • Savage-240G

可以觀察到左上角是 C:
嗯…我沒有特別去單測所以速度會受影響
並沒有到達網路上大家所測試的速度
但已經很接近啦~
而且硬碟使用容量已經有一半了,並不是
空數據了,這會影響到測速
測速小知識:
  • 當系統碟測速會變慢
  • 全新且空資料測速才能達到最快速度

切割後壽命減短

有人說,切割後壽命變短,假設系統是30G你切了30G
那麼你只會使用到這30G,用不到另一區,SSD是有壽命的
最好不要切割讓他整顆去平均分攤才能長壽
這個資料比較少看到,可能很多人不知道
SSD沒有像傳統硬碟那樣明確的切割了磁區,他的磁區
是模擬出來的,就是說即便你切10G,而你確實也
只用那10G,他還是整顆在分擔使用
問題來啦~因為是模擬的所以有人提出切越多越慢的概念
我保持的看法是
或許切割真的會掉速,但並沒有他們說的慢
嗯…有時間有多的硬碟我再來試試看
切100個分區看他速度會多慘XDD
實際到底如何,可能要去挖論文了XDD
有人是做方面的研究的話,歡迎提出來長個知識

轉移IDE驅動的系統碟

前置任務

要真應急才這麼做,這會出現許多不可預知問題的
首先要先補AHCI的驅動,這部分Win8以上就內建了
不用補,Win7自行爬文一下吧XDD 有些麻煩
可以參考 It天空
補完之後記得Win7還要修改登錄檔
我在做Win10的時候並沒有修改

靠Bug去轉

AMD有一個選項可以讓 port4/5 模擬成 IED
這個就是關鍵了,因為你要是切成 AHCI 沒驅動
根本進不去,於是呢以IED模式開啟系統
把 系統碟插在 IDE Port上,就這樣開進系統
由於系統偵測到AHCI就可以安裝AHCI驅動了
安裝完畢再將他切成AHCI模式,就開進去了