文章程式碼顯示

2018年3月10日 星期六

《筆記》談談C++語言 - 1:輸入/出串流、範圍解析運算子

與 C語言 不同的是 C++ 文檔其副檔名以 *.cpp 為主;C語言 則是以 *.c 做為副檔名結尾

對於註解程式碼,事實上 C 語言只支援使用 /* ..... */ 的方式進行註解

但很顯然的,我們在前面那些教學文中多次使用 " // " 的方式進行註解(原本是 C++ 才支援)

這與編譯器能否混用有關

輸入/出串流(對應於 C語言的 scanf 與 printf)

#include "iostream"

int number1;

int main() {
 std::cout << "Hello C++ in Visual Studio 2017" << std::endl;
 std::cout << "This is your first project." << std::endl;
 std::cout << "Enter a number : ";
 std::cin >> number1;
 std::cout << number1 << " * " << number1 << " = " << number1 * number1 << std::endl;
 //system("Pause");

 return 0;
}



程式碼 : 

第一行 : 此為標準 C++ 從標準函是庫引入 輸入/輸出串流標頭檔 <iostream> 的內容,任何成是凡事要將資料輸出到螢幕或是藉由鍵盤輸入資料時皆需要載入此標頭檔

Hint :
在前面的系列文中 C語言 我們也有 #include 一些文件例如 stdio.h stdlib.h 等等,而在 c++ 則是改為 iostream 。事實上 C++ 兼容於 C 語言,故兩者是可以混用的。若你想在 c++ 的文件中使用 pirntf 也是可以的,但你需要 #include "stdio.h"。可參考連結一連結二 (程式碼於文末補充)


第 6 ~ 10 行 :  std::cout 我們拆解成三部份來看

std 表示後面的 cout 這個名稱,是屬於「名稱空間(namespace)」std。名稱空間是 C++ 新增的特性之一,我們對此的了解暫時只需要到這裡就可以了,更深入的部分待後續章節在討論。

雙冒號 :: 表示一元解析運算子

cout 則用來搭配 "<< 串流插入運算子(stream insertion operator)" ,做為輸出字串的用途

endl 為 "串流操作子(stream manipulator),是 endline 的縮寫。做為強迫顯示的用途

Hint : 對於某些系統來說會將輸出資料先累積起來,直到累積得數量夠多才會一次輸出。使用 endl 可以強迫將這些資料馬上輸出,並且清空緩存區的資料

cin 用來搭配 ">> 串流擷取運算子(stream extration operator)",做為從鍵盤輸入資料的用途

#include 

using namespace std;

int number1;

int main() {
 cout << "Hello C++ in Visual Studio 2017" << endl;
 cout << "This is your first project." << endl;
 cout << "Enter a number : ";
 cin >> number1;
 cout << number1 << " * " << number1 << " = " << number1 * number1 << endl;
 //system("Pause");

 return 0;
}


由於每次都要用 std:: 加上 cout 或 cin 或 endl 太麻煩了,故我們可以使用第三行的

using namespace std;

如此一來後續就可以直接省略 std:: 語句

Hint :
第 13 行的 system("Pause"); 可視讀者使用的編譯器來選擇性使用,因我用 Eclipse 這個編譯器其在介面下方有可以輸出/入 字串的 terminal ,故不需要使用。

但,如果你使用 Visual Studio 等等的編譯器,可能它展現資料的方式是使用 console (也就是命令提示介面視窗,像古早時期 DOS 會出現的那種),此種方式若沒有在最後一行加入 pause 則當程式執行完畢後整個視窗會跳掉,造成一閃而過的情況發生,不例於我們進行學習。

範圍解析運算子

之前我們提過區域變數以及全域變數的特性,並且我們有提到「作用域」這個專有名詞

例如當我們先宣告了一個全域變數 a 後,又在某個 Block 內宣告一個區域變數 a ,則此時全域變數的 a 將會被暫時隱藏起來

C++ 提供範圍解析運算子(::) 雙冒號可在某個區域變數的範圍內存取同名的全域變數

首先我們先複習一下之前的區域變數以及全域變數

#include "stdio.h"
#include "stdlib.h"

int number = 66; // global

int main() {

 printf("number = %d\n",number);  // 此處會列印出全域變數

 int number = 77; // 宣告一個同名(number)的區域變數

 printf("number = %d\n",number);  // 此處會印出區域變數

 {
  int number = 88;    // 我們在更內層中,宣告一個同名的區域變數
  printf("number = %d\n",number); // 此時會印出這個更深層的區域變數
 }

 printf("number = %d\n",number);  // 這邊因為跳出(14-17行的)Block,故又會印出第 10 行的區域變數

 return 0;
}


Hint :  只要有 #include "stdio.h" 就可以用 printf 函數(因 C++ 兼容 C語言)

接著我們將全部都加上一元範圍範圍解析運算子(::)

#include "stdio.h"
#include "stdlib.h"

int number = 66; // global

int main() {

 printf("number = %d\n",number);

 int number = 77;
 printf("number = %d\n",::number); 

 {
  int number = 88;  
  printf("number = %d\n",::number); 
 }

 printf("number = %d\n",::number);

 return 0;
}

發現其皆會抓取到第 4 行所宣告的全域變數


Hint :
在本章節最一開始時對於 std 也有使用範圍解析運算子,如 std::cout。

我們可以想像成 cout 存在於 std 這個範圍空間中(雖然我們並沒有解釋 std 到底是什麼樣的空間,因為他藏在底層裡面隱藏起來了),我們只不過把它抓出來用而已(有點像是前面提到的 struct 裡面抓成員變數出來)

而在上例中我們使用 ::number 去取用全域變數 number
也可以想像成我們是對這個 "文件" 去尋找 number


補充 :

#include "iostream"
// 經過實測,使用 Eclipse 甚至不用#include "stdio.h" 也可以使用 printf 函數
// 當然有加入是最正規的,端看不同的編譯器是否有這樣子支援而已
#include "stdio.h" 

using namespace std;

int number1;

int main() {
 cout << "Hello C++ in Visual Studio 2017" << endl;
 cout << "This is your first project." << endl;
 cout << "Enter a number : ";
 cin >> number1;
 cout << number1 << " * " << number1 << " = " << number1 * number1 << endl;

 printf("\n");
 printf("number1 = %d", number1);
 //system("Pause");

 return 0;
}


上例示範了 C++ 與 C語言 的混用

↓↓↓ 連結到部落格方針與索引 ↓↓↓

Blog 使用方針與索引