C 語言中的多維數(shù)組與我們在數(shù)學(xué)中學(xué)習(xí)到的多維數(shù)組是一致的。如果你還不知道什么是多維數(shù)組也沒有關(guān)系。多維數(shù)組可以看成是之前學(xué)習(xí)過的數(shù)組的擴展。它能讓你完成一些僅僅依靠一維數(shù)組沒有辦法完成的事情。讓很多事情完成的更為簡單。
在 C 語言中字符串的應(yīng)用比較多,所以在這里我們實現(xiàn)一個函數(shù),函數(shù)功能是將一串給定的字符串中的大寫字符全部轉(zhuǎn)換為小寫字符。
在 C 語言中,相同的數(shù)字可以用不同的數(shù)制來表示。也就是十進制的數(shù)字可以等價的表示為二進制或者十六進制。那么對于二進制來說,可以進行逐個數(shù)字之間,也就是每一個數(shù)字位的運算。這種運算也廣泛的存在我們?nèi)粘淌褂玫臄?shù)字電路中。其實計算機的運算原理最底層就是位運算,也就是 0 和 1 的運算。
作為 C 語言程序的入口 mian 函數(shù)很多時候會在啟動的時候從外界傳入一些參數(shù)到程序內(nèi)部。
運算符是用來對于變量或者常量施加運算的符號。這一節(jié)是一個介紹性章節(jié),會將 C 語言中出現(xiàn)的常用的操作符列舉在這里。在后面的章節(jié)中,會對于重點的運算符有詳細的介紹。運算符可以分為以下幾種:算數(shù)運算符;關(guān)系運算符(又可以叫做比較運算符);邏輯運算符;位運算符;復(fù)合賦值運算符;指針運算符;其它運算符(除上面類型外的類型)。
在講解變量之前,我們先來看一段代碼:int x;int y=0;char z='A';x=6;在上面這段代碼中出現(xiàn)的 x、y、z 都是一個 C 變量。變量是編程語言中不可或缺的組成部分。它承載這存貯數(shù)據(jù)以及計算結(jié)果等等功能,顧名思義變量就是可以再計算執(zhí)行過程中變化的量。這節(jié)課我們來學(xué)習(xí)下到底什么是變量。
通過 C 語言程序來測試字節(jié)序非常簡單,大致思路如下:定義一個整形變量,然后將 0xAABBCCDD 賦值給該變量。按照從低地址到高地址的順序打印此變量的內(nèi)容。將打印結(jié)果的順序和 0xAABBCCDD 的順序進行對比,觀察二者的變化。代碼片段如下: 1 #include <stdio.h> 2 3 void check_endian() 4 { 5 int n = 0xAABBCCDD; 6 7 unsigned char *ptr_n = (unsigned char*)&n; 8 9 for (int i=0; i < 4; ++i){ 10 printf("%X\n", *ptr_n++); 11 } 12 }代碼中有兩個需要注意的地方:Tips:需要將 int 型變量 n 的地址賦值給了 unsigned char 型指針變量,如果是賦值給 char 型變量,那么打印結(jié)果是:FFFFFFDDFFFFFFCCFFFFFFBBFFFFFFAA原因是 printf 在打印的時候會將 char 提升為 int,0xAA,0xBB 最高位是 1,所以會當做符號位擴展。如果是 unsigned char,會提升為 unsigned int,符號位擴展是 0。打印結(jié)果的時候用 %x 或者 %X 進行格式化輸出。C 語言程序輸出結(jié)果:DDCCBBAA從輸出結(jié)果可以看出我的系統(tǒng)是以小端序來存儲整數(shù)的。
如果你想要從事下面的工作,那么 C 語言將是你非常好的一個選擇:從事需要直接操作操作硬件的編程的嵌入式設(shè)備開發(fā),不需要操作系統(tǒng)的支持。比如我們常見的冰箱,洗衣機等等的控制;嵌入式操作系統(tǒng)和實時操作環(huán)境下的開發(fā);基于 Linux 操作系統(tǒng)下的一些應(yīng)用程序。主要是中間層面應(yīng)用的開發(fā),直接可以與底層硬件交互,而本身又不直接與最終用戶進行交互;音頻和視頻的解碼器和編碼器等;協(xié)議棧的開發(fā)。
C 語言與大多數(shù)計算機語言一樣是按照語句的順序逐條執(zhí)行的。如同流水一樣,從上到下順序執(zhí)行。這就如同我們每天的日常生活,對于上班族來說,就是起床,洗漱,吃早飯,上班,午飯。下班,晚飯,睡覺。感覺一切都平淡無奇。但是如果你想去購買一臺電腦怎么辦?這不是一件每天都發(fā)生的流水事件,而且你需要在有足夠的錢的情況下才能購買。這個時候,你就要在滿足有錢的條件下打破原有的生活順序,去賣場購買一臺電腦。這就是生活中的分支。在程序設(shè)計中同樣存在這樣的分支。
在集成環(huán)境中,編譯 C 語言一般只需要在菜單中選擇 運行 或者 調(diào)試運行 即可。也可以通過相關(guān)的快捷鍵來直接編譯運行程序。要是只編譯不運行,那么里面會有 編譯 選項和與之對應(yīng)的快捷鍵。這時程序只是編譯,并不會運行。對于初學(xué)者來說建議大家不使用 IDE, 而是直接使用文本編輯器來編輯程序。大家不要擔心,我不會推薦諸如 VIM,EMACS 這種上個世紀的產(chǎn)物,因為太小眾了。這里建議大家使用微軟的 Visual Studio Code, 簡稱 VSCode。這個文本編輯器,現(xiàn)代,多功能,多種操作系統(tǒng)下都可以使用,功能強大,可以根據(jù)自己的需要安裝插件擴展功能。
本節(jié)課程我們主要學(xué)習(xí)了如何創(chuàng)建一個支持 C/C++ 的項目。本節(jié)課程的重點如下:掌握如何創(chuàng)建支持 C/C++ 的項目;掌握如何從 Java 中調(diào)用 C/C++ 函數(shù)。
命令 pip3 uninstall package-name 卸載名稱為 package-name 的第三方模塊。卸載 requests 模塊,示例如下:C:\>pip3 uninstall requestsUninstalling requests-2.23.0: c:\python3\lib\site-packages\requests-2.23.0.dist-info\installer c:\python3\lib\site-packages\requests-2.23.0.dist-info\license c:\python3\lib\site-packages\requests-2.23.0.dist-info\metadata c:\python3\lib\site-packages\requests-2.23.0.dist-info\record c:\python3\lib\site-packages\requests-2.23.0.dist-info\top_level.txt c:\python3\lib\site-packages\requests-2.23.0.dist-info\wheel c:\python3\lib\site-packages\requests\__init__.py ...Proceed (y/n)? y Successfully uninstalled requests-2.23.0卸載 requests 模塊時,首先列出該模塊相關(guān)的文件,在刪除這些文件前,程序要求用戶輸入 y 進行確認。用戶輸入 y 后,pip3 就會卸載該模塊。
>>> dict(){}創(chuàng)建一個空的字典>>> dict(a='A', b='B', c='C'){'a': 'A', 'b': 'B', 'c': 'C'}通過命名參數(shù)創(chuàng)建包含 3 個鍵值對的字典>>> pairs = [('a', 'A'), ('b', 'B'), ('c', 'C')]>>> dict(pairs){'a': 'A', 'b': 'B', 'c': 'C'}>>>定義列表 pairs由 3 個元組構(gòu)成每個元組包含兩項:鍵和值列表 pairs 包含了 3 個鍵值對創(chuàng)建一個包含 3 個鍵值對的字典
Python 的模塊是一個普通的 Python 文件,例如 os 模塊對應(yīng)的文件是 os.py。os 模塊是 Python 自帶的模塊,如果 Python 安裝到 C:\Python3 目錄下,在 C:\Python3\Lib 目錄下能找到 os.py,即 os.py 的完整路徑是 C:\Python3\Lib\os.py。sys.path 是一個列表,列表保存了多個路徑名:>>> import sys>>> sys.path['C:\\Python3\\DLLs', 'C:\\Python3\\lib', 'C:\\Python3\\lib\\plat-win', 'C:\\Python3\\lib\\lib-tk', 'C:\\Python3', 'C:\\Python3\\lib\\site-packages', 'C:\\Python3\\lib\\site-packages\\win32']Python 使用 ‘import os’ 引入 os 模塊,注意:Python 使用模塊名而不是模塊的完整路徑引入模塊。Python 查找模塊 os 的過程如下:在 sys.path[0] 指向的目錄 C:\Python3\DLLs 下查找文件 os.py在 sys.path[1] 指向的目錄 C:\Python3\lib 下查找文件 os.py…
賦值運算符是為指定變量分配值的符號。下標列出了常用 Java 中常用的賦值運算符:運算符描述例子=簡單的賦值運算符。將值從右側(cè)操作數(shù)分配給左側(cè)操作數(shù)。c = a + b將a + b的值賦給c+=加和賦值運算符。它將右操作數(shù)添加到左操作數(shù),并將結(jié)果分配給左操作數(shù)。c + = a等于c = c + a-=減和賦值運算符。它從左側(cè)操作數(shù)中減去右側(cè)操作數(shù),并將結(jié)果分配給左側(cè)操作數(shù)。c -= a等效于c = c – a*=乘和賦值運算符。它將右操作數(shù)與左操作數(shù)相乘,并將結(jié)果分配給左操作數(shù)。c *= a等效于c = c * a/ =除和賦值運算符。它將左操作數(shù)除以右操作數(shù),并將結(jié)果分配給左操作數(shù)。c /= a等于c = c / a
我們通常意義上的常量其實和英語中的常量這個單詞不是一個意思,漢語中的常量對應(yīng)的是 Literal(字面值),而不是 Constant(常量)。這里我們分別講一下這兩個內(nèi)容,大家就會有自己的對于“常量”的相關(guān)的認識了。
我們有些時候需要使用一些固定的名稱來代表固定的數(shù)值,比如在計算你的課程成績的時候,有的課程會出現(xiàn)用英文字母 A-F 來打分,這個時候你需要換算為一個固定的分值來計算平均分。要實現(xiàn)這個功能,你可以選擇在程序的開始定義一系列的常量,但是這樣的定義會非常繁瑣,而且不方便維護。這個時候就出現(xiàn)了一種變量的類型,枚舉。
#include <stdio.h>int main(){ int *a, b = 100, *c; printf("a value = %p, a address = %p, a point value = %d\n", a, &a, *a); printf("b value = %d, b address = %p\n", b, &b); printf("c value = %p, c address = %p, c point value = %d\n", c, &c, *c); a = &b; printf("a value = %p, a address = %p, a point value = %d\n", a, &a, *a); c = a; printf("c value = %p, c address = %p, c point value = %d\n", c, &c, *c); printf("b value = %d, b address = %p\n", b, &b); return 0;}運行結(jié)果:示例中的運行結(jié)果中的十六進制所表示的地址每臺機器都會不太一樣,甚至每次運行都會發(fā)生變化。因為操作系統(tǒng)每次為系統(tǒng)分配的內(nèi)存都不太一樣。a value = 0x7fffaf0005a0, a address = 0x7fffd2942a28, a point value = -1991643855b value = 100, b address = 0x7fffd2942a24c value = 0x7fffd2942b20, c address = 0x7fffd2942a30, c point value = 1a value = 0x7fffd2942a24, a address = 0x7fffd2942a28, a point value = 100c value = 0x7fffd2942a24, c address = 0x7fffd2942a30, c point value = 100b value = 100, b address = 0x7fffd2942a24示例程序中聲明了一個整數(shù)類型的指針 a ,同時還聲明并初始化了一個整數(shù)類型的變量 b 。我們首先展示了此時此刻指針變量 a 中存儲的值,也就是一個內(nèi)存地址,這個地址為 0x7fffaf0005a0 ,同時 a 變量本身的地址為 0x7fffd2942a28 ,此時其存儲的內(nèi)存地址中所存儲的值為 -1991643855 。這里需要說明的是, a 變量此時還沒有初始化,沒有賦值,里面存儲的數(shù)值是隨機的,所以其代表的值也是隨機的,必須在賦值以后才能使用。這點和所有的變量的使用是一致的。變量 b 的存儲的數(shù)值為 100 ,其內(nèi)存的地址為 0x7fffd2942a24 。指針變量 c 中存儲的數(shù)值是地址 0x7fffd2942b20 ,其本身的地址是 0x7fffd2942a30 ,里面存儲的地址中存儲的數(shù)值為 1 。然后我們進行了一次賦值的操作。這里的賦值操作,就是將變量 b 的地址賦給了變量 a。這個時候你會發(fā)現(xiàn)變量 a 中存儲的數(shù)值變成了變量 b 的地址,而變量 a 自己的地址是沒有發(fā)生變化的,而變量 a 中所存儲的地址中的值也編程了變量 b 中所存儲的值 100 。指針之間的賦值就比較直接,和普通變量的賦值是一樣的,只要直接賦值就可以了。下面的表格展示了這一系列的變化初始狀態(tài)變量名變量中數(shù)值地址指針地址中數(shù)值a0x7fffaf0005a00x7fffd2942a28-1991643855b1000x7fffd2942a24c0x7fffd2942b200x7fffd2942a301賦值后變量名變量中數(shù)值地址a0x7fffd2942a240x7fffd2942a28b1000x7fffd2942a24c0x7fffd2942a240x7fffd2942a30
>>> x = {'a':'A', 'b':'B'}>>> x['c'] = 'C'>>> x{'a':'A', 'b':'B', 'c':'C'}在第 1 行,創(chuàng)建一個具有 2 個鍵值對的字典;在第 2 行,在字典中增加一個鍵值對:鍵為 ‘c’,值為 ‘C’;在第 3 行,顯示新增后的字典;在第 4 行,新增后的自動包含 3 個鍵值對。
Command line arguments in C/C++10.2. Arguments to mainHow to write a good C main function
表達式作為函數(shù)體,返回值的類型可以省略,可以利用 Kotlin 的類型推導(dǎo)功能,推測出函數(shù)返回值的類型。fun sum(a: Int, b: Int, c: Int): Int { return a + b + c}//可簡寫成以下形式fun sum(a: Int, b: Int, c: Int) = a + b + c
創(chuàng)建完 test.py 后,進入 C 盤根目錄,使用 dir 命令查看 C 盤根目錄,確認在 C 盤目錄下存在文件 test.py,如下圖所示:使用 dir 命令查看 C 盤根目錄 然后,以 Python 源文件名 test.py 作為參數(shù)調(diào)用 python 命令,如下圖所示:以 Python 源文件名作為參數(shù)調(diào)用 python 命令 命令 python test.py 執(zhí)行 Python 程序 test.py,輸出結(jié)果為:helloworld
在 Java 中接口多繼承是支持的,Kotlin 依然也支持。那么一起來看下在 Kotlin 對于上述多繼承問題是如何解決的呢?package com.imooc.testinterface A { fun invoke()}interface B : A { override fun invoke() { println("B invoke") }}interface C : A { override fun invoke() { println("C invoke") }}class D : B, C { //override fun invoke() = super<B>.invoke()//通過super中泛型類型指定繼承B接口的方法,所以最后輸出"B invoke" override fun invoke() = super<C>.invoke()//通過super中泛型類型指定繼承C接口的方法,所以最后輸出"C invoke"}fun main() { val d = D() d.invoke()}
#include <stdio.h>int main(){ char a[5]; char b[] = "abcde"; char c[6] = {'a', 'b', 'c', 'd', 'e', '\0'}; a[0] = 'H'; a[1] = 'e'; a[2] = 'l'; a[3] = 'l'; a[4] = '\0'; printf("a = %s\n", a); for (int i = 0; i < 5; i++) { printf("a[%d] = %c\n", i, a[i]); } for (int i = 0; i < 6; i++) { printf("b[%d] = %c\n", i, b[i]); } printf("c = %s\n", c); return 0;}運行結(jié)果:a = Hella[0] = Ha[1] = ea[2] = la[3] = la[4] =b[0] = ab[1] = bb[2] = cb[3] = db[4] = eb[5] =c = abcde示例程序里展示了單獨聲明字符串 a ,并且在后面為其賦值,初始化變量 b 和 c。接著,我們通過屏幕打印語句查看了字符串的內(nèi)容,并且通過循環(huán)語句,輸出了字符數(shù)組中存儲的字符串。字符串在 C 語言中是不安全存在的,請大家切記如果不是在初始化的時候用雙引號的形式賦值,在使用數(shù)組賦值的時候,請大家一定不要忘記末尾的結(jié)束符號。如果缺少了這個符號,大家可以嘗試看看,看看內(nèi)存使用錯誤的奇妙。
Object 的鍵是無序的,當鍵可以隱式轉(zhuǎn)換為數(shù)值時,在循環(huán)的時候就會被優(yōu)先排序。這也是為什么要求最好不要使用 Number 類型作為對象的屬性。var obj = { c: 'C', 3: 3, a: 'A', 1: 1,}for (let key in obj) { console.log(key, obj[key])}// 1 1// 3 3// c C// a AMap 會記錄插入的順序,存放的是鍵值對的組合,并且不會做類型轉(zhuǎn)換。Map 可以用 forEach 循環(huán)。var map = new Map();map.set('c', 'C').set(3, 3).set('a', 'A').set(1, 1);map.forEach((item, key) => { console.log(key, item, typeof key)})// c C string// 3 3 "number"http:// a A string// 1 1 "number"從上面的代碼中,使用 typeof 去檢查 key 的數(shù)據(jù)類型,可以看出 Map 并不會對鍵做類型轉(zhuǎn)換。
命令 pip3 install --upgrade package-name 升級名稱為 package-name 的第三方模塊。命令 從網(wǎng)站 pypi.org 下載指定名稱的第三方模塊的最新版本,然后自動安裝升級。升級名為 requests 的第三方模塊,示例如下:C:\>pip3 install --upgrade requestsRequirement already up-to-date: requests in c:\python3\lib\site-packagesRequirement already up-to-date: certifi>=2017.4.17 in c:\python3\lib\site-packages (from requests)Requirement already up-to-date: idna<3,>=2.5 in c:\python3\lib\site-packages(from requests)Requirement already up-to-date: chardet<4,>=3.0.2 in c:\python3\lib\site-packages (from requests)Requirement already up-to-date: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in d:\addon\py36\lib\site-packages (from requests)
有三個參數(shù)時,第三個參數(shù)是替換結(jié)束的位置,不包括結(jié)束的位置。['a', 'b', 'c'].fill(4, 1, 2); // ["a", 4, "c"]['a', 'b', 'c'].fill(4, -3, -2); // [4, "b", "c"]['a', 'b', 'c'].fill(4, -3, 1); // [4, "b", "c"]['a', 'b', 'c'].fill(4, -2, 1); // ["a", "b", "c"]上面的代碼中,通過上面的示例我們可以總結(jié)一點就是,找到起始位置的元素和結(jié)束位置的元素,如果它們中間有值則把中間的值替換,起始位置的索引必須小于結(jié)束位置的索引,如果沒有則不會被替換。如:第 2 行中 -3 的位置是 “a”,-2 的位置是 “b”,在數(shù)組中 “a” 和 “b” 直接沒有值,但是包含起始的 “a” 所以 “a” 會被替換。第 4 行中第二個參數(shù) -2 位置元素是 “b” 索引是 1,第三個參數(shù) 1 位置的元素是 “a” 索引是 0,起始位置的索引大于結(jié)束位置的索引,所以數(shù)組中沒有符合替換的元素。
在 C 語言中定義的字符串是一個由字符組成的數(shù)組,這個數(shù)組的最后一個元素是一個表示空的字符 \0 。字符串 abcde 在 C 語言中的存儲方式如下char str[]="abcde";--------------------------| a | b | c | d | e | \0 |-------------------------- 0 1 2 3 4 5 索引
>>> db.sadd('set2', 'b')1>>> db.sadd('set2', 'c')1>>> db.sadd('set2', 'd')1創(chuàng)建集合 ‘set2’,向集合 ‘set2’ 中添加元素 ‘b’、‘c’、‘d’>>> db.smembers('set'){'a', 'b', 'c'}>>> db.smembers('set2'){'b', 'd', 'c'}顯示集合 ‘set’ 與 集合 ‘set2’ 包含的成員>>> db.sinter('set', 'set2'){'b', 'c'}>>> db.sunion('set', 'set2'){'a', 'b', 'd', 'c'}db.sinter(‘set’, ‘set2’) 求取集合的交集db.sunion(‘set’, ‘set2’) 求取集合的并集>>> db.sdiff('set', 'set2'){'a'}>>> db.sdiff('set2', 'set'){'d'}db.sdiff(‘set’, ‘set2’) 求取集合的差集在 ‘set’ 中出現(xiàn),在 ‘set2’ 中沒有出現(xiàn)的元素構(gòu)成的集合db.sdiff(‘set2’, ‘set’) 求取集合的差集在 ‘set2’ 中出現(xiàn),在 ‘set’ 中沒有出現(xiàn)的元素構(gòu)成的集合
直接新增數(shù)據(jù)列,需要傳入新增的列索引名,以及該列每行的數(shù)據(jù)項值:# 導(dǎo)入pandas包import pandas as pd# 指定導(dǎo)入的文件地址 默認是file,這里的路徑中省略了 file:/data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第7,8,9,10小節(jié)/execl數(shù)據(jù)demo.xlsx"data = pd.read_excel(data_path)print(data)# --- 輸出結(jié)果 --- 編程語言 推出時間 價格 主要創(chuàng)始人0 java 1995年 45.6 James Gosling1 python 1991年 67.0 Guido van Rossum2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 1995年 59.5 Brendan Eich4 php 2012年 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# 新增數(shù)據(jù)列操作data["new_colume"]=["a","b","c","d","e","f"]print(data)# --- 輸出結(jié)果 --- 編程語言 推出時間 價格 主要創(chuàng)始人 new_colume0 java 1995年 45.6 James Gosling a1 python 1991年 67.0 Guido van Rossum b2 C 1972年 33.9 Dennis MacAlistair Ritchie c3 js 1995年 59.5 Brendan Eich d4 php 2012年 69.9 Rasmus Lerdorf e5 C++ 1983年 75.0 Bjarne Stroustrup f輸出解析:我們通過操作新增 new_colume 列,并指定行值分別為a,b,c,d,e,f,通過輸出結(jié)果可以看到,在數(shù)據(jù)集的最后一列新增了數(shù)據(jù)列內(nèi)容。