C/C++ sizeof 用法與範例

本篇 ShengYu 介紹 C/C++ sizeof 用法與範例,sizeof 是用來計算資料類型在該平台記憶體中所佔用 bytes 數。

以下 C/C++ sizeof 的用法介紹將分為這幾部份,

  • sizeof 基本類型
  • sizeof 自定義類型 struct / class
  • sizeof 資料結構對齊問題

那我們開始吧!

sizeof 基本類型

sizeof 回傳的是 size_t,要 print size_t 的話要用 %zu,才不會遇到型別不對的編譯警告,

cpp-sizeof.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// g++ cpp-sizeof.cpp -o a.out
#include <stdio.h>

int main() {
printf("sizeof(char) %zu\n", sizeof(char));
printf("sizeof(unsigned char) %zu\n", sizeof(unsigned char));
printf("sizeof(short) %zu\n", sizeof(short));
printf("sizeof(unsigned) %zu\n", sizeof(unsigned));
printf("sizeof(int) %zu\n", sizeof(int));
printf("sizeof(unsigned int) %zu\n", sizeof(unsigned int));
printf("sizeof(long) %zu\n", sizeof(long));
printf("sizeof(float) %zu\n", sizeof(float));
printf("sizeof(double) %zu\n", sizeof(double));

return 0;
}

我的平台輸出如下,基本上資料類型有無 unsigned 都是同一個大小,char 的大小是 1 byte,int 的大小是 4 bytes,

1
2
3
4
5
6
7
8
9
sizeof(char)           1
sizeof(unsigned char) 1
sizeof(short) 2
sizeof(unsigned) 4
sizeof(int) 4
sizeof(unsigned int) 4
sizeof(long) 8
sizeof(float) 4
sizeof(double) 8

如果是用 sizeof(變數) 的話,就會計算該變數的資料類型的大小,範例如下,

cpp-sizeof2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// g++ cpp-sizeof2.cpp -o a.out
#include <iostream>
using namespace std;

int main() {
char c = 'a';
short s = 123;
int i = 456;
long l = 789;
float f = 3.5;
double d = 3.14;
cout << "sizeof(char) " << sizeof(c) << '\n';
cout << "sizeof(short) " << sizeof(s) << '\n';
cout << "sizeof(int) " << sizeof(i) << '\n';
cout << "sizeof(long) " << sizeof(l) << '\n';
cout << "sizeof(float) " << sizeof(f) << '\n';
cout << "sizeof(double) " << sizeof(d) << '\n';

return 0;
}

我的平台輸出如下,

1
2
3
4
5
6
sizeof(char)          1
sizeof(short) 2
sizeof(int) 4
sizeof(long) 8
sizeof(float) 4
sizeof(double) 8

如果是用 sizeof 陣列的話,範例如下,

cpp-sizeof3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
// g++ cpp-sizeof3.cpp -o a.out
#include <iostream>
using namespace std;

int main() {
int num[10];
cout << "sizeof(int[10]) " << sizeof(int[10]) << '\n';
cout << "sizeof num " << sizeof(num) << '\n';
cout << "length of num " << sizeof(num) / sizeof(num[0]) << '\n';

return 0;
}

我的平台輸出如下,

1
2
3
sizeof(int[10])  40
sizeof num 40
length of num 10

sizeof 自定義類型 struct / class

sizeof 自定義類型 struct 或 class 的範例如下,

cpp-sizeof4.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// g++ cpp-sizeof4.cpp -o a.out
#include <iostream>
using namespace std;

struct EmptyStruct {};
class EmptyClass {};
struct CharStruct { char c; };
class CharClass { char c; };
class Base {
public:
int a;
};
struct Derived : Base {
public:
int b;
};

int main() {
EmptyClass *p;
Derived d;
Base &b = d;
cout << "sizeof empty struct " << sizeof(struct EmptyStruct) << '\n';
cout << "sizeof empty class " << sizeof(EmptyClass) << '\n';
cout << "sizeof Char struct " << sizeof(struct CharStruct) << '\n';
cout << "sizeof Char class " << sizeof(CharClass) << '\n';
cout << "sizeof pointer " << sizeof(p) << '\n';
cout << "sizeof the Base class " << sizeof(Base) << '\n';
cout << "sizeof the Derived class " << sizeof(Derived) << '\n';
cout << "sizeof the Derived through Base " << sizeof(b) << '\n';

return 0;
}

我的平台輸出如下,不管是空的 struct 或者空的 class 基本開銷就是 1,即使裡面放了一個 char 變數也還是 1,

1
2
3
4
5
6
7
8
sizeof empty struct              1
sizeof empty class 1
sizeof Char struct 1
sizeof Char class 1
sizeof pointer 8
sizeof the Base class 4
sizeof the Derived class 8
sizeof the Derived through Base 4

sizeof 資料結構對齊問題

現代的編譯器幾乎都會進行最佳化,所以有時候某資料結構佔用的 bytes 數可能不是你想像的,原因是因為編譯器會為了運行效能進行最佳化,如下列範例所示,

cpp-sizeof5.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// g++ cpp-sizeof5.cpp -o a.out
#include <iostream>
using namespace std;

struct CharChar { char c; char c2; };
struct CharCharInt { char c; char c2; int i; };
struct IntCharChar { int i; char c; char c2; };
struct CharIntChar { char c; int i; char c2; };
struct CharShortChar { char c; short s; char c2; };

int main() {
cout << "sizeof(CharChar) " << sizeof(CharChar) << '\n';
cout << "sizeof(CharCharInt) " << sizeof(CharCharInt) << '\n';
cout << "sizeof(IntCharChar) " << sizeof(IntCharChar) << '\n';
cout << "sizeof(CharIntChar) " << sizeof(CharIntChar) << '\n';
cout << "sizeof(CharShortChar) " << sizeof(CharShortChar) << '\n';

return 0;
}

我的平台輸出如下,值得注意的是 CharCharInt 手算的話應該為 6,但是編譯器進行最佳化時會變成 8,
而 CharIntChar 會因為順序關係而造成最佳化結果不同變成 12,
CharShortChar 手算的話應該為 4,但是編譯器進行最佳化時會變成 6,

1
2
3
4
5
sizeof(CharChar)       2
sizeof(CharCharInt) 8
sizeof(IntCharChar) 8
sizeof(CharIntChar) 12
sizeof(CharShortChar) 6

通常在跨平台或資料結構的網路通訊中會需要資料對齊,
那麼如果要一定讓它強制對齊的話呢?Windows 與 Linux / macOS 作法不同,
在 Linux / macOS 下是這樣做,要加上 __attribute__((__packed__)),加在前或後都可以,適用於 GCC 編譯器,

cpp-sizeof6.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// g++ cpp-sizeof6.cpp -o a.out
#include <iostream>
using namespace std;

struct __attribute__((__packed__)) CharChar {
char c;
char c2;
};

struct __attribute__((__packed__)) CharCharInt {
char c;
char c2;
int i;
};

struct IntCharChar {
int i;
char c;
char c2;
} __attribute__((__packed__));

struct CharIntChar {
char c;
int i;
char c2;
} __attribute__((__packed__)) charintchar;

typedef struct CharShortChar {
char c;
short s;
char c2;
} __attribute__((__packed__)) CharShortChar_t;

int main() {
charintchar.i = 123;
CharShortChar_t charshortchar;
cout << "sizeof(CharChar) " << sizeof(CharChar) << '\n';
cout << "sizeof(CharCharInt) " << sizeof(CharCharInt) << '\n';
cout << "sizeof(IntCharChar) " << sizeof(IntCharChar) << '\n';
cout << "sizeof(CharIntChar) " << sizeof(CharIntChar) << '\n';
cout << "sizeof(CharShortChar) " << sizeof(CharShortChar) << '\n';

return 0;
}

我的平台輸出如下,

1
2
3
4
5
sizeof(CharChar)       2
sizeof(CharCharInt) 6
sizeof(IntCharChar) 6
sizeof(CharIntChar) 6
sizeof(CharShortChar) 4

在 Windows 下是這樣做,#pragma pack 這寫法原本只適用於 Visual C++ 編譯器,但後來 GCC 為了相容性也加入了這個語法的支援,

cpp-sizeof7.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// g++ cpp-sizeof7.cpp -o a.out
#include <iostream>
using namespace std;

//#pragma pack(push)
//#pragma pack(1)
#pragma pack(push, 1)
struct CharChar { char c; char c2; };
struct CharCharInt { char c; char c2; int i; };
struct IntCharChar { int i; char c; char c2; };
struct CharIntChar { char c; int i; char c2; };
struct CharShortChar { char c; short s; char c2; };
#pragma pack(pop)

int main() {
cout << "sizeof(CharChar) " << sizeof(CharChar) << '\n';
cout << "sizeof(CharCharInt) " << sizeof(CharCharInt) << '\n';
cout << "sizeof(IntCharChar) " << sizeof(IntCharChar) << '\n';
cout << "sizeof(CharIntChar) " << sizeof(CharIntChar) << '\n';
cout << "sizeof(CharShortChar) " << sizeof(CharShortChar) << '\n';

return 0;
}

我的平台輸出如下,同上,

1
2
3
4
5
sizeof(CharChar)       2
sizeof(CharCharInt) 6
sizeof(IntCharChar) 6
sizeof(CharIntChar) 6
sizeof(CharShortChar) 4

有關資料結構對齊問題的詳細分享無法在本篇完整解釋以後再另文說明。

以上就是 C/C++ sizeof 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

sizeof operator - cppreference.com
https://en.cppreference.com/w/cpp/language/sizeof
c++ - what is the difference between __attribute__((__packed__)); and #pragma pack(1) - Stack Overflow
https://stackoverflow.com/questions/32208805/what-is-the-difference-between-attribute-packed-and-pragma-pack1

其它相關文章推薦
如果你想學習 C/C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ typedef 用法與範例
C/C++ define 用法與範例

C/C++ define 用法與範例

本篇 ShengYu 介紹 C/C++ define 用法與範例。

以下 C/C++ define 用法介紹將分為這幾部份,

  • C/C++ define 基本用法
  • C/C++ define 單行巨集的範例
  • C/C++ define 多行巨集的範例
  • C/C++ 取消巨集
  • C/C++ define 來簡化函式
  • C/C++ 預定義巨集

那我們開始吧!

C/C++ define 基本用法

以下為 C/C++ define 語法,define 前面加上 #,define 最後面不需加上;分號,define 的順序跟 typedef 是不一樣的,容易搞混,需要特別注意一下,

1
#define <NEW_NAME> <EXIST_NAME>

例如,define PI 為 3.1415,define HELLO_WORLD_STR 為 “Hello World”,

1
2
#define PI 3.1415
#define HELLO_WORLD_STR "Hello World"

C/C++ define 單行巨集的範例

以下示範 C/C++ define 單行巨集,

cpp-define.cpp
1
2
3
4
5
6
7
8
9
10
11
// g++ cpp-define.cpp -o a.out
#include <stdio.h>

#define PI 3.1415
#define HELLO_WORLD_STR "Hello World"

int main() {
printf("PI: %f\n", PI);
printf("%s\n", HELLO_WORLD_STR);
return 0;
}

輸出如下,

1
2
PI: 3.141500
Hello World

C/C++ define 多行巨集的範例

以下示範 C/C++ define 多行巨集,多行可以用反斜線換行,

1
2
3
4
#define MACRO(arg1, arg2) do { \
stmt1; \
stmt2; \
} while(0)

例如:兩整數交換的 SWAP 可以這樣寫,

1
2
3
4
#define SWAP(x, y) \
int tmp = x; \
x = y; \
y = tmp;

實際的範例如下,

cpp-define2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// g++ cpp-define2.cpp -o a.out
#include <stdio.h>

#define SWAP(x, y) \
int tmp = x; \
x = y; \
y = tmp;

int main() {
int a = 3;
int b = 5;
printf("a: %d, b: %d\n", a, b);
SWAP(a, b);
printf("a: %d, b: %d\n", a, b);
return 0;
}

輸出如下,

1
2
a: 3, b: 5
a: 5, b: 3

C/C++ 取消巨集

C/C++ 取消巨集語法如下,使用 #undef 後面接上巨集名稱,

1
#undef <macro name>

undef 取消巨集範例如下,

cpp-define3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// g++ cpp-define3.cpp -o a.out
#include <stdio.h>

#define DEBUG
#undef DEBUG

int main() {
#ifdef DEBUG
printf("DEBUG\n");
#else
printf("NO DEBUG\n");
#endif
return 0;
}

輸出如下,

1
NO DEBUG

C/C++ define 來簡化函式

define 巨集可以用來簡化函式,例如我們 define 一個 DEBUG_PRINT 巨集用來將資料輸出到錯誤輸出上,

1
2
3
4
5
6
#define DEBUG_PRINT(fmt, ...) do { fprintf(stderr, fmt, __VA_ARGS__); } while (0)

// 使用範例
DEBUG_PRINT("error message");
// 使用範例
DEBUG_PRINT("error code: %d", errorcode);

或 Android 常見的 log 輸出函式,

1
2
3
4
5
6
7
8
#include <android/log.h>

#define TAG "MYDEBUG"
#ifdef DEBUG
#define ALOGD(...) do { __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__); } while (0)
#else
#define ALOGD(...) do {} while (0)
#endif

C/C++ 常用巨集

1
2
3
4
5
#define MIN(a, b) (a < b ? a : b)
#define MAX(a, b) (a > b ? a : b)
#define ADD(x, y) (x + y)
#define SUB(x, y) (x - y)
#define SWAP(x, y) int tmp = x; x = y; y = tmp;

寫 macro 時有時會遇到一些陷阱,例如乘法 MULT 這個巨集如下,

1
#define MULT(x, y) x * y

上面這種寫法乍看沒什麼問題,實際上會因為 MULT(1+1,2+2); 這樣使用後被展開成 1+1*2+2 = 5 而造成結果不對。
所以會改成下這樣寫法,加上括號,

1
#define MULT(x, y) (x) * (y)

這樣寫的話展開成 (1+1)*(2+2) = 2*4 = 8 結果就正確了。
最保險的方式是把每個變數都用括號把它包起來,這也就是為什麼常看到別人寫的巨集都多了好多括號的原因。

C/C++ 預定義巨集

以下是 C/C++ 常用的預定義巨集,

1
2
3
4
5
__FILE__,原始碼檔案路徑  
__LINE__,原始碼行數
__FUNCTION__,函式名稱
__func__,函式名稱
__VA_ARGS__,可變引數的巨集

以上就是 C/C++ define 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其他參考
c preprocessor - #define macro for debug printing in C? - Stack Overflow
https://stackoverflow.com/questions/1644868/define-macro-for-debug-printing-in-c
(Android系统)android log机制浅析_威猛の小脑斧的博客-CSDN博客___android_log_write
https://blog.csdn.net/lele_cheny/article/details/34858503
用macro的技巧 | 技術筆記
http://twmht.github.io/blog/posts/cc/macro.html

其它相關文章推薦
如果你想學習 C/C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ typedef 用法與範例
C/C++ sizeof 用法與範例

C/C++ typedef 用法與範例

本篇 ShengYu 介紹 C/C++ typedef 用法與範例,typedef 是將一個資料類型取一個別名,之後就可以用新的別名來宣告變數,以便簡化宣告語法。

以下 C/C++ typedef 的用法介紹將分為這幾部份,

  • C/C++ typedef 基本用法
  • C/C++ typedef struct 取別名

那我們開始吧!

C/C++ typedef 基本用法

C/C++ 中 typedef 是關鍵字,typedef 是將一個資料類型取一個別名,之後就可以用新的別名來宣告變數,通常是為了簡化宣告語法,讓程式碼更容易閱讀,以下為 C/C++ typedef 基本用法,

typedef 最後面需要加上 ; 分號,語法如下,

1
typedef <EXIST_TYPE> <NEW_TYPE>;

例如,將 char 取 int8_t 別名,將 int 取 int32_t 別名,

1
2
typedef char int8_t;
typedef int int32_t;

C/C++ typedef struct 取別名

這邊介紹 C/C++ 使用 typedef 把某個 struct 取別名,以下示範用 typedef 將 struct point 取一個 point_t 別名,之後宣告時就可以使用新的 point_t 別名,就可以省去加上 struct,藉此達到簡化宣告語法,

cpp-typedef.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// g++ cpp-typedef.cpp -o a.out
#include <stdio.h>
#include <string.h>

typedef struct point {
int x;
int y;
} point_t;

int main() {
point_t p1;
p1.x = 3;
p1.y = 5;
printf("x: %d\n", p1.x);
printf("y: %d\n", p1.y);

return 0;
}

輸出如下,

1
2
x: 3
y: 5

另外還可以把 struct 的定義跟 typedef 分開寫,像這樣寫,

1
2
3
4
5
6
struct point {
int x;
int y;
};

typedef struct point point_t;

以上就是 C/C++ typedef 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
如果你想學習 C/C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ struct 用法與範例
C/C++ enum 用法與範例
C/C++ union 用法與範例

Android adb install INSTALL_FAILED_UPDATE_INCOMPATIBLE 解決方法

本篇介紹 Android adb install apk 出現 INSTALL_FAILED_UPDATE_INCOMPATIBLE 解決方法。

adb 指令的安裝方式可以參考這篇

adb install apk INSTALL_FAILED_UPDATE_INCOMPATIBLE 錯誤

用 adb install abc.apk 時遇到 INSTALL_FAILED_UPDATE_INCOMPATIBLE 錯誤訊息時怎麼辦,

解決方法:
簡單的方式是移除原本的套件 package,用 adb uninstall 移除該套件名 package name,如果移除套件 com.xxx.xxx 就這樣下,

1
adb uninstall com.xxx.xxx

參考
android - INSTALL_FAILED_UPDATE_INCOMPATIBLE when I try to install compiled .apk on device - Stack Overflow
https://stackoverflow.com/questions/11891848/install-failed-update-incompatible-when-i-try-to-install-compiled-apk-on-device

相關主題
Android adb 基本用法教學
Android adb logcat 基本用法教學
Android adb logcat 出現 read unexpected eof 解決方法
Android adb 同步時間/設定時間
Android adb shell input 事件用法
Android adb forward 通訊埠轉發用法教學

3種免費遠端桌面軟體推薦

本篇 ShengYu 介紹 Windows/macOS/Ubuntu 跨平台免費遠端桌面軟體。

以下3種免費遠端桌面軟體推薦分為

  • TeamViewer
  • Chrome Remote Desktop
  • AnyDesk

TeamViewer

TeamViewer 是一款用於遠端存取以及遠端控制和遠端維護電腦和其他終端裝置的軟體,發布於 2005 年。功能性被逐步擴大。TeamViewer 不需要註冊,非商業領域免費使用,這有助於軟體的廣泛傳播。

多平台支援性與特色
Server伺服端(被控制)支援平台:Windows / macOS / Linux / Chrome OS / Raspberry Pi
Client客戶端(控制)支援手機行動裝置:Yes
需要外網IP:不需要
需要帳號:不需要註冊帳號

下載安裝
電腦版(Windows/macOS/Ubuntu):Chrome 遠端桌面
Chrome 擴充:Chrome Remote Desktop
Android:TeamViewer遠端控制版本
iOS:TeamViewer Remote Control

官網連結:https://www.teamviewer.com/

Chrome Remote Desktop

Chrome 遠端桌面是 Google 開發的遠端桌面軟體工具,允許使用者通過 Google 開發的專有協議(內部稱為Chromoting)遠端控制其他電腦的桌面。特色為快速且完全免費。需要 Chrome 瀏覽器跟 google 帳號。

多平台支援性與特色
Server伺服端(被控制)支援平台:Windows / macOS / Linux
Client客戶端(控制)支援手機行動裝置:Yes
需要外網IP:不需要
需要帳號:需要註冊 Gmail 帳號

下載安裝
電腦網頁版:Chrome 遠端桌面
Chrome 擴充:Chrome Remote Desktop
Android:Chrome 遠端桌面
iOS:Chrome 遠端桌面

AnyDesk

AnyDesk 是一款由德國公司 AnyDesk Software GmbH 推出的遠端桌面軟體。使用者可以通過該軟體遠端控制電腦,同時還能與被控制的電腦之間進行文件傳輸。是近幾年的新興免費遠端桌面軟體。

多平台支援性與特色
Server伺服端(被控制)支援平台:Windows / macOS / Linux / FreeBSD / Raspberry Pi / Chrome OS
Client客戶端(控制)支援手機行動裝置:Yes
需要外網IP:不需要
需要帳號:不需要註冊帳號

下載安裝
Windows:AnyDesk 遠端桌面軟體
macOS:AnyDesk 遠端桌面軟體
Android:AnyDesk 遠端桌面軟體
iOS:AnyDesk 遠端桌面軟體

官網連結:https://anydesk.com

以上就是3種免費遠端桌面軟體的介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
【遠端桌面】4款2022年最常用免費遠端控制軟體分享!TeamViewer、Chrome、AnyDesk、Wayk Now
https://kikinote.net/157800

LINE 分享螢幕畫面(電腦螢幕畫面與手機螢幕畫面)

本篇記錄 LINE 分享螢幕畫面的方法,要確定 LINE 的版本是 5.23.0 以上,才有分享螢幕畫面的功能,Windows LINE 5.23.0 大約是 2020.3.16 上線,macOS LINE 5.23.0 大約是 2020.3.18 上線。

LINE 分享電腦螢幕畫面

以下為網路上找的不錯文章,

疫情應援,LINE電腦版5.23.0「分享螢幕畫面」功能全新升級!
https://www.nova.com.tw/article/ef/content/615ac9d381911

疫情應援,LINE電腦版5.23.0「分享螢幕畫面」功能全新升級!
https://official-blog-tw.line.me/archives/82467713.html

LINE共享螢幕功能教學-用LINE就能和多人即時分享電腦螢幕畫面,手機、電腦都能看。
https://www.pkstep.com/archives/57538
教學是 windows 介面,分享時如果有雙螢幕的話,會讓你選擇要分享哪一個螢幕,

LINE 分享螢幕教學大公開【適用手機、電腦版 LINE】
https://tw.imyfone.com/line/line-screen-sharing/
教學是 windows 介面,這版的畫面比較接近目前的版本

【科技新知】如何用LINE即時分享自己的「螢幕畫面」給好友?電腦/手機版都適用
https://www.jyes.com.tw/news.php?act=view&id=815
教學是 windows 介面,

LINE 分享手機螢幕畫面

LINE 分享螢幕教學大公開【適用手機、電腦版 LINE】
https://tw.imyfone.com/line/line-screen-sharing/

【科技新知】如何用LINE即時分享自己的「螢幕畫面」給好友?電腦/手機版都適用
https://www.jyes.com.tw/news.php?act=view&id=815

其它相關文章推薦
Windows 10 螢幕錄影
Ubuntu 桌面錄影軟體

Windows 10 螢幕錄影

本篇 ShengYu 介紹 Windows 10 螢幕錄影的用法與快捷鍵,以及錄完後的檔案儲存路徑在哪。

按下 Windows鍵 + G 快捷鍵就能叫出 Windows 錄影的選單,
Windows鍵 + ALT + R 進行錄影功能,再按一次則結束錄影,
Windows鍵 + Alt + Print Screen 進行螢幕截圖,

要找遊戲短片和螢幕擷取畫面的儲存路徑的話,請選取 開始 > 設定 > 遊戲 > 擷取 然後選取 開啟資料夾

以上就是 Windows 10 螢幕錄影的介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
Windows 螢幕錄影教學:Win10 內建錄影軟體
https://tw.imyfone.com/pc-tips/screen-record-windows/
內建 Windows 10 螢幕錄影功能:用遊戲列錄製軟體教學影片
https://www.playpcesor.com/2017/09/windows-10-record-screen.html
Windows 中我的遊戲短片和螢幕擷取畫面儲存在何處?

其它相關文章推薦
Ubuntu 桌面錄影軟體
LINE 分享螢幕畫面(電腦螢幕畫面與手機螢幕畫面)

Shell Script rename prefix 重新命名加上前綴字

本篇 ShengYu 介紹 Shell Script 重新命名加上前綴字的方法。

以下示範 Shell Script 將 *.jpg 檔案重新命名都加上 NEW_ 前綴字,

1
2
3
4
for filename in *.jpg
do
mv "$filename" "NEW_${filename}"
done

寫成一行的話就變成這樣,

1
$ for filename in *.jpg; do mv "$filename" "NEW_${filename}"; done;

結果會是這樣,

1
2
xxx.jpg # 修改前
NEW_xxx.jpg # 修改後

也可以用 rename 這個指令,也有一樣的效果,

1
$ rename 's/(.*)$/NEW_$1/' *.jpg

以上就是 Shell Script rename prefix 重新命名加上前綴字介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
How to rename with prefix/suffix?
https://stackoverflow.com/questions/208181/how-to-rename-with-prefix-suffix

其它相關文章推薦
如果你想學習 Shell Script 相關技術,可以參考看看下面的文章,
Linux rename 用法與範例
Shell Script 新手入門教學
Shell Script 四則運算,變數相加、相減、相乘、相除
Shell Script if 條件判斷
Shell Script for 迴圈
Shell Script while 迴圈
Shell Script 讀檔,讀取 txt 文字檔

Linux rename 用法與範例

本篇 ShengYu 介紹 Linux rename 的用法與範例,rename 是實用的重新命名工具,可以搭配正規表達式來使用,比起手動重新命名實在方便很多,尤其是要大量重新命名時特別有幫助,可以省下許多時間。

基本上 rename 跟 mv 跟差不多一樣功能的指令,但有些功能無法相通,所以在 macOS 下就沒有 rename 指令,就用 mv 取代即可。

rename 重新命名

將 xxx.jpg 加上 NEW_ 前綴字,使用的 rename 的指令如下,

1
2
$ rename 's/(.*)$/NEW_$1/' xxx.jpg
=> NEW_xxx.jpg

一次改大量的 jpg 副檔名的話

1
$ rename 's/(.*)$/NEW_$1/' *.jpg

另外用 shell script 也可以達成

1
$ for filename in *.jpg; do mv "$filename" "NEW_${filename}"; done;

也可以使用擴展正規表達式這樣寫

1
2
#$ mv {,NEW_}xxx.jpg
$ for filename in *.jpg; do mv {,NEW_}"$filename"; done;

把 JPEG 副檔名改成 jpg 副檔名

1
$ rename .JPEG .jpg *.JPEG

用 shell script 也可以達成

1
$ for filename in *.JPEG; do mv -i "$filename" "${filename%%.*}.jpg"; done

rename 實際案例

原先我的照片是 IMG_*.jpg 開頭,影片是 VID_*.mp4 開頭,但是這樣同時間的照片跟影片會分開檢視,這樣在編輯與分類時特別不方便,比較好的方式應該是照片跟影片一律改成 XXX_ 開頭,例如以我的 pixel 手機為例,就一律重新命名成 PXL_ 開頭,要區分照片跟影片的話用副檔名區分就可以了,

例如,我要將 IMG_ 前綴字換成 PXL_ 前綴字,

1
2
IMG_20210522_170609.jpg # 修改前
PXL_20210522_170609.jpg # 修改後

那麼就這樣使用

1
$ rename 's/IMG_(.*)$/PXL_$1/' IMG_20210522_170609.jpg

jpg 照片的話就這樣下,

1
$ rename 's/IMG_(.*)$/PXL_$1/' *.jpg

改用 shell script 就這樣寫,

1
2
3
4
for filename in $(\ls -d *.jpg)
do
mv $filename $(echo $filename | sed -e 's/IMG_/PXL_/')
done

mp4 影片的話就這樣下,

1
$ rename 's/VID_(.*)$/PXL_$1/' *.mp4

改用 shell script 就這樣寫,

1
2
3
4
for filename in $(\ls -d *.mp4)
do
mv $filename $(echo $filename | sed -e 's/VID_/PXL_/')
done

以上就是 Linux rename 用法與範例的介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
How to rename with prefix/suffix?
https://stackoverflow.com/questions/208181/how-to-rename-with-prefix-suffix
file management - Is there a linux command like mv but with regex? - Super User
https://superuser.com/questions/70217/is-there-a-linux-command-like-mv-but-with-regex

其它相關文章推薦
Shell Script rename prefix 重新命名加上前綴字
Linux 常用指令教學懶人包
Linux cut 字串處理用法與範例
Linux sed 字串取代用法與範例
Linux grep/ack/ag 搜尋字串用法與範例
Linux du 查詢硬碟剩餘空間/資料夾容量用法與範例
Linux wget 下載檔案用法與範例

macOS 安裝 Node.js 的方法

本篇記錄一下 macOS 用 brew 安裝 Nodejs 的方法。

macOS brew 安裝 nodejs

macOS 用 brew 安裝 nodejs 的方法如下,撰寫本文當下最新是 node v18,

1
brew install node

舊版 macOS brew 安裝 nodejs

我的舊 macOS 環境為 macOS 10.13.4 以及 Xcode Version 9.1,
安裝最新的 node (v18)時會先安裝相依性套件 z3,而出現編譯錯誤,顯示需要支援 c++17 的編譯器,
只好用 brew 安裝指定舊版的 Nodejs,目前可以安裝 Node v12 / Node v14,經測試過都可以順利安裝成功,Node v16 會遇到無法辨識的編譯選項 -stdlib=libc++

1
2
3
4
brew install node@12
brew unlink node
brew link node@12 # 失敗的話換 brew link --overwrite node@12
node -v

安裝完後 node v12 的執行檔路徑在 /usr/local/Cellar/node@12/12.22.12_1/bin/nodebrew link node@12 後是將 /usr/local/bin/node 指向 /usr/local/Cellar/node@12/12.22.12_1/bin/node

如果要移除 Node v12 的話就不能用 brew uninstall node,要用

1
brew uninstall node@12

另外可以看看 https://formulae.brew.sh/formula/node 的舊版相容資訊。

以上就是 macOS 安裝 Node.js 的方法介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其他參考
javascript - How to brew install specific version of Node? - Stack Overflow
https://stackoverflow.com/questions/44803721/how-to-brew-install-specific-version-of-node