計算機協會招新課01
第一部分:一門基礎的編程語言
走計算機行業不管哪個方向,會一兩門編程語言都是必須的,第一部分講一下如何快速的掌握一門基礎的編程語言。
這里以c語言作為講解對象
首先我們要明晰一個基本的概念,就是模塊化
c語言是一個模塊化了的語言,這個模塊化體現在很多方面,比如函數,比如結構體,比如多文件。
首先說一下函數
函數是c語言的基本單位
一個c語言程序,就是由一個個變量拼成結構體,一個個結構體與函數拼成文件,最后再由一個個文件拼成最后的整個程序
那么函數是怎么樣的呢?
void main()
{
//代碼內容
}
這就是一個最簡化的函數(當然我們通常不用void)
這個函數的結構是這樣的
void main() //函數聲明 簡單理解為表示創建一個函數
{ //代碼塊開始
//代碼塊可以簡單理解為我們要運行的一段代碼
} //代碼塊結束
這里的void是指返回值的類型,void表示沒有返回值,為什么函數需要返回值呢?因為我們在執行一個函數的時候通常是需要它來實現某個功能的,如果沒有返回值我們就不知道它有沒有成功執行,或者不知道它的執行結果了(譬如執行開平方以后我們沒有收到返回值,平方是開完了,但是結果捏?????)
而且有些時候我們的系統在執行函數的時候也強制要求返回值(一些系統,不是所有系統)
綜上,我們的程序最好提供一個返回值
因此在事實上我們的一個函數表達出來其實是這樣的
typename main(){
//函數內容
return volue;
}
這里的typename常用的有 int char double long short float
分別對應為整數,字符,雙精度浮點數,長數,短數,浮點數,浮點數就是帶小數點的數,計算機處理浮點數有誤差,double比float精准一些
這里我們所寫的函數名字叫main
main函數也就是程序的主函數,主函數就是程序開始執行的地方,也就說不管在主函數前面后面寫多少函數都沒有用,計算機只有找到主函數才能開始執行
由於是主函數,所以我們的返回值自己是沒有辦法用到了,但是有的計算機系統可能會要求,因此通常的要求是返回一個0,告訴系統程序正確執行完成,也就是
int main()
{
//函數內容
return 0;
}
這里我們運行一下這個程序給大家看看結果
(展示)因為我們什么都沒有執行,所以也什么都沒有顯示
那么怎么證明我們的程序真的執行成功了呢?這里我們再增加一行用於顯示的指令
printf("hello world")
printf是c語言里的打印(顯示到屏幕)語句,這句話的意思是顯示hello world
加上之后我們再來運行一下
如左下角,加上以后我們的命令行就顯示出了我們要顯示的內容,這證明本喵剛才認真講了沒有胡說八道(驕傲)
可能剛才有銀還意識到一個問題,就是剛才的程序比上面說的多了一行
#include <stdio.h>
這一句的意思又是蝦米捏?
后面加的字符是c語言里的預處理指令,就是編譯器程序執行前預先處理的指令,用來補足程序運行中需要的一些東西
這個#include就是包含頭文件的意思
include <stdio,h>
的意思就是這個程序要包含頭文件stdio.h里面的內容,stdio.h是c語言編譯器自帶的一個頭文件,包含了輸入輸出的函數之類的一些常用的功能函數,printf()其實就是一個函數,它在stdio文件里面,我們使用的printf就是調用了程序外部頭文件stdio.h里面的print函數。
剛才咱們已經說了,c語言由很多函數構成,下面咱們再定義一下別的函數來個多函數的程序
#include
int dnlm()
{
printf(" pass your mother" );
return 0;
}
int main()
{
dnlm();
return 0;
}
由於這個不是主函數了所以函數名就可以自己起了,不過這里要注意,函數名不能和關鍵字(c語言里面已經被占用的詞)同名
這里我們起名(dnlm)
吶,這里左下角就正確顯示了
這里是先定義了dnlm函數然后在主函數里面用=調用了它
dnlm();
就醬,我們寫了一個多個函數的c語言程序,(在學習編程的初期可以先不用考慮多文件,先從一個文件寫起)
然后下面我們講一坨選擇分支結構
這個選擇分支結構它是這個樣子的
if()
{
//如果條件成立執行
}
else
{
//如果條件不成立執行
}
這里我們添加一個dnlf並且聲明母親父親兩個整數來測試一下
#include
int dnlm()
{
int mother=30;//聲明整數mother等於30
int father=20; //聲明整數father等於20
if (mother>father) //如果mother大於father
{
printf(" pass your mother" ); //顯示
}
else //否則
{
printf(" pass your father" ); //顯示
}
return 0;
}
int main()
{
dnlm();
return 0;
}
運行結果正確的顯示在了左下角。
這樣一來證明我們的選擇結構發揮了它應有的效果
剛才講完了選擇分支結構,這次我們從循環結構開始講,一課時之內把c語言入門講完,然后看看時間能不能夠講一些其他的東西。
循環結構
首先是while循環,這是平常會經常用到的一個循環
while(循環條件){ //代碼內容}
while循環的結構是這樣的,首先判斷循環條件是不是成立,例如循環條件是變量a>=2,那么當a大於等於2的時候,就會執行代碼內容一次,然后再次判斷a是不是還大於等於2,如果是的話再執行一次。直到有一次發現a不再大於等於2了,才結束循環開始執行循環外面的內容。
這樣一來的話,實際上也就是說,我們在寫這種循環的時候,里面一定要寫改變循環條件的代碼,否則循環條件一直不變就變成死循環了。
while循環是先判斷然后才決定執不執行的,所以while循環最少會執行0次,也就是說如果一開始條件就不成立的話就一次都不執行。
與之相對的是do。。。while循環
do{ //代碼內容}while()
do。。。while和while相反,dowhile是先做了再說,做一遍到做完以后再判斷,是不是條件成立 ,條件成立的話繼續循環,條件不成立的話到此為止,繼續往下執行,do while循環是至少會執行一次的循環。
與while系列循環用的同樣多的就是for循環了
for(i=100;i>=0;i--){ //代碼內容}
for循環的條件分為三部分,第一部分是聲明控制循環的變量,比如聲明個i=100,第二個部分和while的控制條件一樣是用來判斷循環執不執行,最后一個部分是用來聲明控制變量的變化,就和while一樣,for也需要改變控制條件來防止死循環,不過for直接在控制條件里就可以寫好改變控制變量的語句。
以上是循環結構的三種語句。
跳轉語句
下面進行今天的第二部分,跳轉語句
c語言里的跳轉語句其實就是goto
語法也很簡單,在任意一個地方立下flag,然后就可以隨時goto到這個地方了
:lable1
//此處省略兩百萬億行
goto lable1
就可以直接飛回flag
goto用的好的話不僅可以跳轉還可以實現各種循環,不過goto很容易出現不知道飛到了哪里去但是編譯器不報錯導致查錯人員頭比地球還大的現象,因此一般的來說,不建議使用goto語句。
數組
數組部分也很簡單,
我們平常聲明一個變量a,可以儲存一個數據。
我們現在聲明一個數組a[100],就可以儲存100個數據
數據類型 數組名[數組長度]
可以通過a[0-99]來分別使用這100個數據,就不用寫100遍聲明變量了,而且如果我們要查找的數有好幾個特點,還可以使用二維或者多維數組。
比如a[1][2][3][4][5][6][7]就是七維數組里第二組的第三小組的第四小組的第五小組的第六小組的第七小組的第八個數
這里要注意數組里面排序序號是從零開始的,第一個內容的編號是0,所以數組名加數字實際訪問到位置是數字加一的位置存的數據。
從本質上而言,數組其實就是一種指針的應用方式。
指針
語言里面指針是核心精髓所在,所謂指針,就是畫一個箭頭指向數據儲存的地方
我們平常聲明一個變量,a=100,大概就相當於在白紙上划了一部分叫做a區,然后往里面記錄了一個數字100,100寫在a這個地方。
這塊a區所在的位置就叫做a的地址
c語言里面和地址有關的有兩個符號,一個是&,取地址符,一個是*,是指針的標記
我們平常創建變量的時候是這樣的
int a;
我們創建指針時候是這樣的
int* p;
標上一個*
表示這個變量p存儲的是int變量的地址。
我們平常給變量賦值的方法是這樣的
a=100;
我們給指針賦值的時候是這樣的
p=&a;
這里的&a的意思就是取得a的地址
看到這里大家可能會有所疑惑,這個指針和變量到底有什么區別呢?
這里舉一個簡單的例子來說明指針和直接調用變量的區別
坐在隔壁的小明想要抄你的試卷,他看了一下a區,把數字抄走了,這是b=a,
坐在隔壁的小明想要抄你的試卷,他拿走了你的試卷,這是b=&a
前者只是拿走了數據,后者拿走的數據的地址,那么這會導致什么呢?
當小明想要修改卷子的時候——
前者,b修改了卷子上的數值,a的卷子沒事,因為b只是抄走了一個數據
后者,b修改了卷子上的數值,a驚叫一聲:卧槽你把我卷子改了干啥!!!
這就是使用變量的值和使用變量的指針的區別
BUT!!!為什么我們需要使用指針呢????
當然是因為有些時候我們必須使用指針!
舉個糖炒栗子!比如我們想要在某個函數里修改函數外的值的時候,我們就必須得使用指針。
這里我們就需要一點關於函數調用、形參與實參的知識。
有些時候我們要用的函數會需要傳入一些數值,比如我們寫一個求和的函數
int sum(int a,int b) //聲明一個返回值是整數的函數,使用時需要傳入整數a和整數b
{
return a+b; //返回a+b的值
}
然后我們在使用的時候就需要傳入兩個值
sum(x,y) //x和y是之前已經弄好的存了值的變量
sum(10,20)//或者這樣直接給兩個數值
這里面的a和b就叫形參,也可以簡單粗略地理解為參數所需的形式,x和y就是實參,可以簡單粗略的理解為實際傳入的參數。
在程序運行到調用sum函數的時候就會創建兩個臨時的變量a和b,然后把x和y的值傳給a和b。
這里就出現了不使用指針無法解決的問題——如果我們想要把存儲的結果還存在x里呢?
當然,這樣其實還能解決,x=sum(x,y)
就行了,但是如果我們要存到的地方不確定呢?比如根據sum計算結果的不同存到不同的地方,是不是沒有辦法啦!
而使用指針就可以很方便(才怪)的解決這個問題,我們不傳入值,而是把地址傳過去,小明不久可以直接修改你的試卷了嗎?
#include <stdio.h>
int main(int argc, char const *argv[])
{
int x=1;
int y=2;
sum (&x,&y);
return 0;
}
int sum(int* a,int* b)
{
*a=*a+*b;
return 0;
}
這樣就完美的解決了這個問題。
那么這里出一道小題,如果想要修改指針變量int* a的值應該怎么辦呢?
int sum(int** a,int** b)
{
*a=*a+*b;
return 0;
}
當然是傳入指針的指針!
指針是可以一層套一層的,int************************************************ a
都可以!
回到剛才,講指針的時候我們有說數組是指針的一種應用,是什么意思呢?現在我們就可以解答這個問題了,數組就是根據你的需求創建了好多挨在 一起的空間,然后數組的名字就是一個指針,指向第一塊地方,然后數組[]里跟不同的數字就是把指針往后移不同的長度,指到不同的地方。
比如a[3],其實也就是*(a+3)的意思,你把a[3]寫成*(a+3),*(3+a),3[a]都可以的,都是一樣的東西。
這里也解答了為什么數組前面要加int double之類的類型的問題,因為聲明數組的時候需要創建出一些地方來存數據,數組前面的數據類型是用來標識每一塊地方多大的。
很高興大家能聽我說這么多,今天我要講的東西就這么多。
大家有興趣的話也可以自己寫點東西練習一下,比如寫個學生信息管理系統什么的,這節課提供的知識是足夠的。這里也宣傳一下我們的協會,
追求技術是一場漫長的旅程,很高興在這里與你們相逢。