海之音
INFOR 36th 學術長 @小海_夢想特急_夢城前
從0開始的異世界生活程式人生
講師
Index
:你知道電研花了一個半小時的小社就把這堆東西講完了嗎
:那當然 那可是BrineTW我的偶像欸
說真的 我相信你們都比我清楚
從C開始
從C開始
機器碼
程式語言發展
組合語言
C
0000 0000 000000010000
0000 0001 000000000001
0001 0001 000000010000
0001 0001 000000000001
section .data
msg db 'Hello, world!',0xA
len equ $-msg
section .text
global _start
_start:
mov edx,len
mov ecx,msg
mov ebx,1
mov eax,4
int 0x80
mov ebx,0
mov eax,1
int 0x80
#include<stdio.h>
int main(){
printf("Hello, world\n");
return 0;
}
(亂找的 這不是Hello world)
低階 -> 高階
不是給人看 -> 給人看的
所以別再抱怨C/C++很難讀懂了
從C開始
C
C
#include<stdio.h>
int main(){
printf("Hello, world\n");
return 0;
}
#include<iostream>
int main(){
std::cout << "Hello, world" << std::endl;
return 0;
}
C++
Python
print("Hello, world\n")
Java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello, world!");
}
}
從C開始
C/C++
C
C++
Python
C/C++的運作
組語
編譯
機器碼
組譯
C++
其實這原本應該是807⁸⁰⁷要講但他不在 部分簡報by 807⁸⁰⁷
IDE(整合式開發環境)
VScode(文字編輯器)
VScode
編譯器(MSYS2)
pacman -S mingw-w64-ucrt-x86_64-gcc
編譯器(MSYS2)
6. 前往環境變數(可以用左下角的搜尋)
7. 選取 系統變數 中的 Path 然後按下 編輯
8. 按 新增 然後貼上這段路徑
如果有如果有變更路徑: 去資料夾找 你改的路徑+\ucrt\bin
9. 確定 確定 確定
C:\msys2\ucrt64\bin
編譯器(MSYS2)
編譯器(MSYS2)
1. 按 Ctrl+` 開啟終端機
2. 輸入
出現👇代表安裝成功
g++ --version
g++ (Rev10, Built by MSYS2 project) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
其實這原本應該是807不該講但他不在 簡報by807
WSL(Linux子系統)
Windows Subsystem for Linux
超好用的東西
WSL(Linux子系統)
按Windows+R 輸入 cmd(開啟cmd)
輸入
按Windows+R 輸入 wsl(開啟wsl)
輸入
wsl --install
sudo apt upgrade
sudo apt install g++ gdb
code .
更新apt
安裝編譯器
開啟vscode
WSL(Linux子系統)
比剛剛快多了
第一次接觸某程式的傳統
做就對了
#include<iostream>
int main(){
std::cout << "hello, world\n";
return 0;
}
Code::Blocks
VScode
程式架構
#include<iostream>
#define io std::ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
/*
可能有其他函式、結構變數
*/
int main(){
io;
std::cout << "hello, world\n";
return 0;
}
<-預處理
<-其他函式區
<-主函式區
Variable: 多變的 那const變數怎麼解釋
變數
int占4 bytes(32位元) -> 儲存範圍
(一格存正負,剩下存數字),以此類推 unsigned int 存
long long 占 8 bytes,範圍
float占 4 bytes,範圍 3.4E +/- 38 (7 位數)
double占 8 bytes,範圍 1.7E +/- 308 (15位數)
short占 2 bytes,範圍
其他型別
char是以ASCII編碼,實際字元作用的範圍只有0~127,但可以存-128~127(或0~255)
當整數被轉成bool時,只有0是false,剩下數字都是true,bool轉成整數時預設是0和1
string在C裡面是字元陣列(後面會提),在C++裡我們有現成的string可以用,等等提
宣告與使用變數
string
string
跳脫字元
作用域
int a = 1; //外層變數
{
int a = 2; //內層變數
}
a = 3;//到這裡{}裡的a就沒有作用了,修改的是外層的那個
修飾字
實際上我更愛scanf/printf
輸出
輸入
優點與缺點
std::ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
C-style Output
int a=3, b=5;
printf("%d %d", a, b);
int a=5;
printf("%p", &a);
C-style Output
int hr, min;
scanf("%d:%d", &hr, &min);
int a, b;
scanf("%2d%2d", &a, &b);
#include <iostream>
int main(){
int a, b;
cin >> a >> b;
cout << a << ' ' << b << '\n';
return 0;
}
#include <stdio.h>
int main(){
int a, b;
scanf("%d%d", &a, &b);
printf("%d %d", a, b);
return 0;
}
EOF
畢竟電腦是電子計算機,會運算是很正常的
運算子
運算子
優先順序:先乘除後加減,然後是位元運算和邏輯運算
不確定時括號是你的超人
用Vector啦
一維陣列
一維陣列
高維陣列
data[0]
data[1]
data[2]
data[3]
data[4]
一維陣列data[5]
data[0][0]
data[1][0]
data[2][0]
data[3][0]
data[4][0]
data[0][1]
data[1][1]
data[2][1]
data[3][1]
data[4][1]
data[0][2]
data[1][2]
data[2][2]
data[3][2]
data[4][2]
二維陣列data[5][3]
高維陣列
(C-style)string
老實說指標沒很常用 我都用參考
指標(pointer)
指標(pointer)
#include<iostream>
using namespace std;
int main(){
int *a = new int;
cout << a << '\n'; //0xbe1560
int b = 5;
int *c = &b;
cout << c << ' ' << *c; //0x70fdfc 5
return 0;
}
指標(pointer)
data[0]
data[1]
data[2]
data[3]
data[4]
類似變數存取
data
data+1
data+2
data+3
data+4
指標
&data[0]
&data[1]
&data[2]
&data[3]
&data[4]
相當於
指標(pointer)
#include<iostream>
using namespace std;
int main(){
int data[5][5];
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
data[i][j]=i*5+j;
}
}
/*
{
{ 0, 1, 2, 3, 4},
{ 5, 6, 7, 8, 9},
{10, 11, 12, 13, 14},
{15, 16, 17, 18, 19},
{20, 21, 22, 23, 24}
}
*/
cout << *(*(data+2)+3); //13
return 0;
}
指標(pointer)
*data
*(*(data+1)) : 5 | *(*(data+1)+1):6 | *(*(data+1)+2):7 | *(*(data+1)+3):8 | *(*(data+1)+4):9 |
---|
*(data+1)
*(*data) : 0 | *((*data)+1) : 1 | *((*data)+2) : 2 | *((*data)+3) : 3 | *((*data)+3) : 4 |
---|
...
參考(reference)
#include <iostream>
using namespace std;
int main() {
int a = 5;
int &b = a;
b = 1;
cout << a; //1
return 0;
}
參考(reference)
if - else 應該不會有人特別去用 switch - case 啦
if-else
// do something
if(condition){
// do something if true
}
else{
// do something if false
}
// do something
if-else
// ...
if(condition1){
//...
}
else{
if(condition2){
// ...
}
else{
// ...
}
}
// ...
// ...
if(condition1){
// ...
}
else if(condition2){
// ...
}
else{
// ...
}
// ...
三元運算子
b=a>0?a:(-a);
while loops
// ...
while(condition){
// ...
}
// ...
// ...
while(cin >> n){
// ...
}
// ...
for loops
// ...
for(初始化; 持續條件; 常駐步驟){
// ...
}
// ...
// ...
for(int i=0; i<n; i++){
// ...
}
// ...
無窮迴圈
while(true){
// ...
}
break, continue
//範例:如果輸入=0就跳出
int n;
while(true){
cin >> n;
if(n==0) break;
// ...
}
//也可以寫成
int n;
while(cin >> n && n!=0){
// ...
}
//範例:輸出輸入的數字
//除非輸入=48763則跳過
int n;
while(true){
cin >> n;
if(n==48763) continue;
cout << n << '\n';
// ...
}
多層迴圈
#include<iostream>
using namespace std;
int main(){
int data[5][5];
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
data[i][j]=i*5+j;
}
}
/*
{
{ 0, 1, 2, 3, 4},
{ 5, 6, 7, 8, 9},
{10, 11, 12, 13, 14},
{15, 16, 17, 18, 19},
{20, 21, 22, 23, 24}
}
*/
cout << *(*(data+2)+3); //13
return 0;
}
重新看一次這份code,應該要能知道為什麼結果是這樣
do while
do{
// ...
} while(condition);
遍歷陣列(C++11以上)
int a[]={0, 1, 2, 3, 4};
for(int i:a) i=0;
for(int i:a) cout << i << ' '; // 0, 1, 2, 3, 4
將陣列內的值分別複製到 i 中,然後跑過a陣列
注意如果是在多維陣列裡,因為陣列就是指標,所以如果修改低維的內容還是會改到值
int a[]={0, 1, 2, 3, 4};
for(int& i:a) i=0;
for(int i:a) cout << i << ' '; // 0, 0, 0, 0, 0
i 的參考分別指向 i[0], i[1]..., i[4]
TIOJ 1007 參考解答
#include <iostream>
#define int unsigned long long
using namespace std;
signed main() {
int n, m;
cin >> n >> m;
int dp[n + 1];
for (int i = 0; i <= n; i++) dp[i] = 0;
dp[0] = 1;
dp[1] = 1;
int temp;
for (int l = 1; l < m; l++) {
temp = dp[0];
for (int j = 1; j <= n; j++) dp[0] += dp[j];
for (int j = n; j >= 2; j--) dp[j] = dp[j - 1];
dp[1] = temp;
}
int ans = 0;
for (int i = 0; i <= n; i++) ans += dp[i];
cout << ans;
return 0;
}
逆向 ZJ b515 參考解答
//字串預處理
#include <iostream>
#include <string>
using namespace std;
int main() {
string temp;
for (auto &i : "A .- B -... C -.-. D -.. E . F ..-. G --. H ....I .. J .--- K -.- L .-..M -- N -. O --- P .--.Q --.- R .-. S ... T -U ..- V ...- W .-- X -..-Y -.-- Z --..") {
if (i == ' ') continue;
if ('A' <= i && i <= 'Z') cout << "\"" << temp << "\", \n", temp = "";
else temp += i;
}
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main() {
const string table[26] = {
".-",
"-...",
"-.-.",
"-..",
".",
"..-.",
"--.",
"....",
"..",
".---",
"-.-",
".-..",
"--",
"-.",
"---",
".--.",
"--.-",
".-.",
"...",
"-",
"..-",
"...-",
".--",
"-..-",
"-.--"};
string input;
cin >> input;
string ans;
for (unsigned int i = 0; i < input.size(); i++) {
ans += table[input[i] - 'A'];
}
cout << ans;
return 0;
}
還有基礎遞迴(recursion)
函式
函式
參數(可無)
回傳值(可無)
函式:處理過程
定義函式
// 宣告+定義
回傳型別 函式名稱(參數型別1 參數1, 參數型別2 參數2...){
定義內容
}
// 只有宣告
回傳型別 函式名稱(參數型別1 參數1, 參數型別2 參數2...);
呼叫函式
參數
回傳值
練習:寫一個函式交換 main() 函式裡兩個整數變數的值
參考解答
#include<iostream>
using std::cout;
void swap(int &a, int &b){
int temp=a;
a=b;
b=temp;
return;
}
int main() {
int a = 5, b = 3;
swap(a, b);
cout << a << ' ' << b; // 3 5
return 0;
}
遞迴(recursion)
遞迴(recursion)
費波那契數列(遞迴Ver.)
int fibonacci(int n) {
if (n == 1 || n == 2) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}
初始狀態:f(1) = f(2) = 1
狀態轉移:f(n) = f(n-1) + f(n-2)
終止時間:n = 1 或 n = 2
練習:利用 求 ,並分析此函式應該會被呼叫幾次(以 n 表示)
再分析如果利用 會被呼叫多少次
你能夠想到的最好作法是什麼?(呼叫次數最少?)
改成 呢?
進階題:求上面求費波那契數列的方法會呼叫多少次函式?(數學)
一點點OOP
物件導向(OOP)淺談
結構變數(struct)
#include <iostream>
using namespace std;
struct person {
double height, weight;
double BMI() {
return weight / (height * height);
}
};
int main() {
person Sea;
Sea.height = 1.813;
Sea.weight = 71.4;
cout << Sea.BMI(); // 21.7221
}
結構變數(struct)
struct person {
double height, weight;
double BMI();
};
double person::BMI(){
return person::weight/(person::height*person::height);
}
struct person {
double height, weight;
struct other{
double length_of_hair;
string favorate_food;
} other_information;
};
結構變數(struct)
struct complex{
int a, b;
complex(int _a, int _b){
a=_a;
b=_b;
}
};
int main(){
complex number(125, 807);
cout << number.a << ' ' << number.b; // 125 807
return 0;
}
struct complex {
int a, b;
complex(int _a, int _b) {
a = _a;
b = _b;
}
complex operator+(complex another) {
return {a + another.a, b + another.b};
}
};
int main() {
complex number1(125, 807), number2(123, 456);
complex sum = number1 + number2;
cout << sum.a << ' ' << sum.b;
return 0;
}
ZJ a271 (可以用struct實作一隻兔子)
寫題目的地方
What is OJ
一些OJ
一些OJ
一些OJ
一些OJ
一些OJ
一些OJ
一些OJ
其他人分享吧
By 海之音