【C編程】開始

編程的流程是先編寫程序文件,再編譯。編程語言有多種,例如 C,Java,Python。C 語言的話,程序文件類型是.c文件。

C語言編譯將生成可執行文件。即,這個文件和app一樣可運行。

A) 編寫.c文件。

雖然是計算機語言,卻是純文本。純文本就是沒有任何文檔格式,比如字體大小設置,只能手輸所有字符。其編輯器可以是任何純文本編輯器,比如我用MacOS TextEdit。

或比較專業的 Sublime Text,其支持批量縮進和不縮進(tab 和 shift tab)、關鍵詞高亮、程序語句編號。但這些功能沒有也可以的。

先寫helloworld.c程序。

#include <stdio.h>

int main() {
  printf("您好,世界。");
  return 0;
} 

B) 編譯

打開操作系統窗口(MacOS Terminal),cd到程序文件所在文件夾(MacOS Terminal輸入cd ,然後從Finder按住一個文件夾,拖進Terminal窗口)。以下默認以MacOS為例。

編譯器有CC Compiler和GCC Compiler兩個。[1]


如果用CC compiler,輸入命令:

cc helloworld.c

編譯完後,可在Finder看到一個新文件:a.out。

如何執行該文件?在Find直接點擊a.out,會跳出Choose Application窗口,只能在Terminal運行之。但為什麼不是直接a.out,而要寫成./a.out。(為什麼?我不知道。)


如果用GCC Compiler,輸入編譯命令:

gcc helloworld.c -o output 

如果gcc helloworld.c,同上一個命令,默認生成a.out。

這命令各平台通用,MacOS,Linux,Windows。

在MacOS output文件的文件類型是Unix executable。

MacOS如何執行output程序?1)直接在Find點擊output。或2)在Terminal輸入./output

C) Debug

如果編譯通不過,根據編譯器的報錯,修改程序文件,即.c文件,可能是語法錯。

如果編譯通過,運行出錯,我們就需要Debug。如何Debug?基本上就是在程序的各個部位不停地printf(比如printf變量值)。

所以,C語言的語法是什麼?

我們需要考慮如下內容。我們通過具體的編程來看細節,下面只說明概念。

  1. 框架。
    程序文件的格式,頭尾,比如,c 文件的框架是文件頭#include <stdio.h>,主程序int main() {/*很多語句在這裡*/ return 0;}

  2. 變量類型、定義和賦值(variable data type, declaration, assignment)
    data_type_name variable=value;
    variable=value;
    但字符串變量的賦值不完全如此,本文的重點是介紹字符串。

  3. 數學函數(math)
    除了算術,加減乘除,最重要的是初等函數公式,像指數函數exp(x)、三角函數(如cos(x))。

  4. if 判斷語句(conditionals)
    比如:if (condition) {/*Do something*/}

  5. 循環語句(loop)
    比如:While (condition) {}

  6. function 定義
    function定義在頭部。
    比如:return_value_data_type functionname(parameters){}

  7. 遞歸調用(recursion)
    function 自己調用自己,例如漢諾塔算法。

  8. 打印到顯示器
    printf("請輸入一個字符:");

  9. 用戶輸入數據
    scanf("%c", &c); 這是從鍵盤輸入一個字符。

  10. 輸入文件
    fopen(filename, 讀寫權限);

  11. 輸出文件
    fprintf(filename, 內容);
    fclose(filename);

  12. 註釋
    //單行註釋
    /*多行註釋*/
    註釋在編程中的最多用的,主要用於程序算法說明、閱讀和維護,團隊協作。


以下參考 W3C 的 C tutorial [2],我來談C編程的難點,如字符串操作、內存管理、畫圖。本文講字符串的操作。

C的data type 常用的有int整數型,double小數型(即實數),char字符型,但字符串是char數組,沒有單獨的data type。如何定義,如何賦值?我寫在下例的註釋中。核心是:無法直接等於號賦值,string_name="blabla",這是不行的。只能通過字符串拷貝函數strcpy(string_name, "blabla")賦值。

BTW,C的data type是嚴格的,不但有定義名,還有printf format specifier,例如,int myNum=3; printf("%i", myNum); 這裡%i與data type相應。string沒有獨立的data type,卻有獨立的format specifier:%s。這是因為char是單獨字符,如果要打印一串字符,printf用%s來連續打印多個字符,直到字符串的結束符\0(捺零)。

C的字符有三個系統保留字符,不能直接輸入,這樣輸:捺杠\\,單引號\',雙引號\"

// Array and String,array_string.c

#include <stdio.h>
#include <string.h>/*用於數組操作的頭文件,頭文件就是把那個文件加載至這裡,這樣那裡定義的函數都可以用。例如字符串長度計算函數strlen。*/


int main(){
int i=0;
int length;

/*整數數組*/
int myNumbers[] = {10, 25, 50, 75, 100};

printf("%zu\n", sizeof(myNumbers));  // Prints 20
length =sizeof(myNumbers)/sizeof(myNumbers[0]);  

for (i=0; i<length;i++){
printf("myNumber[%i] is %i.\n", i, myNumbers[i]);
}

/*實數數組*/
/*計算數組長度*/
double myValues[] = {1.1, 2.2, 3.3};
length = sizeof(myValues) / sizeof(myValues[0]);

printf("數組長度%d\n", length);  // Prints 3

/*多維數組
    2D arrays (like int scores[3][4]) are great for storing things like scores, game boards, or spreadsheets
    3D arrays (like int cube[2][3][4]) can represent more complex structures like a set of tables or levels in a game
*/
/*這一部分拷貝自W3C tutorial,目的是了解數組是表達矩陣的data type。*/

int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };

int j;
for (i = 0; i < 2; i++) {
  for (j = 0; j < 3; j++) {
    printf("%d\t", matrix[i][j]);
  }
printf("\n");
} 

/*以下我們講string。*/
/*Since strings are actually arrays in C, you can access a string by referring to its index number inside square brackets [].*/
char greetings[] = "Hello World!";
printf("%s\n", greetings);
printf("%c\n", greetings[3]);

char hw[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0'};/*string 最後有\0結尾,算一個字符*/
printf("%s\n", hw);

printf("%zu\n", sizeof(greetings));   // Outputs 13,將\0計算在內
printf("%zu\n", sizeof(hw));  // Outputs 13

char txt[] = "It\'s alright.";
printf("%s\n", txt);

/*字符串長度計算函數strlen*/
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
printf("%zu\n", strlen(alphabet));//不包含\0結尾符

char* firstName = "Johnnie";
char* surname = "B. Goode";
printf("firstName length is %zu\n", strlen(firstName));//不包含\0結尾符
printf("surname length is %zu\n", strlen(surname));//不包含\0結尾符

/*兩個字符串比較函數strcmp*/
//Ref: https://www.w3schools.com/c/ref_string_strcmp.php
char myStr1[] = "ABCD";
char myStr2[] = "ABCd";//d ASCII 100, D ASCII 68
printf("d ASCII code is %i, while D ASCII code is %i.\n", 'd', 'D');
int cmp = strcmp(myStr1, myStr2);
if (cmp > 0) {
  printf("%s is greater than %s\n", myStr1, myStr2);
} else if (cmp < 0) {
  printf("%s is greater than %s\n", myStr2, myStr1);
} else {
  printf("%s is equal to %s\n", myStr1, myStr2);
}

/*如何定義string,方便以字符串賦值。
定義是:char string_name[100]; 
賦值是:strcpy(string_name, "I am bewildered by C char array, pointer, and %s.");*/

/*兩個字符串連接起來的函數strcat。*/
/*Concatenate Strings*/
char str1[100]="Hello ";
char str2[100]="World!";

//Concatenate str2 to str1 (result is stored in str1)
strcat(str1, str2);

// Print str1
printf("Concatenate string %s\n", str1);

/*拷貝string到string variable,這是賦值的方法。*/
// String copy
strcpy(str1, str2);
printf("Copy string %s\n", str1);


strcpy(str1, "How to assigned a string? Namely a char array. ");

strcpy(str2, "How to assigned a string? Namely a char array. ");

int result = strcmp(str1, str2);

if (result == 0) {
printf("Strings are equal.\n");
} else if (result > 0) {
printf("\"%s\" is greater than \"%s\".\n", str1, str2);
} else {
printf("\"%s\" is less than \"%s\".\n", str1, str2);
}

// String assignment

/* 定義字符串,方法1)char temp[]="blabla"; 方法2)char *temp="blabla"; 這兩個定義都限定了分配的內存的長度為這一串字符的長度,如果給這變量拷貝一個過長的字符串,程序運行會abort。所以上文我們給str1,str2各設置了100 bytes。
 
我來介紹指針pointer,即帶*的變量。指針即內存地址,通常是八字節的一個整數。例如下文tmp1是一個地址,如果printf("%p", tmp1);地址的format specifier是%p。*tmp1即這個地址的存儲所存的數據,數據類型char format specifier是%c,例如printf("%c", *tmp1);*/

char *tmp1 = "How to assigned a string variable? Namely a char array. ";
printf("Pointer tmp1 address is %p. Address is %zu bytes.\n", tmp1, sizeof(tmp1));/*\n是換行。只有換行,才看得清楚。有時我連用兩個\n\n。%zu是sizeof函數返回值的format specifier,正整數。*/

printf("Data in tmp1 address is %c.\n", *tmp1);
strcpy(str1,tmp1);

char tmp2[]= "strcpy.";
strcpy(str2, tmp2);

strcat(str1, str2);

printf("%s\n", str1);

return 0;
}

參考:


  1. How To Compile And Run a C/C++ Code In Linux,2025-7-23,https://www.geeksforgeeks.org/cpp/how-to-compile-and-run-a-c-c-code-in-linux/ ↩︎

  2. C Tutorial, W3C, https://www.w3schools.com/c/c_output.php ↩︎

posted @ 2025-10-11 19:37  Dersu  阅读(6)  评论(5)    收藏  举报