0. 複習
0.1 循環
while(表達式)
{
}
do
{
}while(表達式);
for(初始化循環變量;判斷條件;循環變量的變化)
{
}
一般比較明確循環次數的時候,使用for
不太明確循環次數的時候,一般使用while
兩個控制語句:
break: 跳出循環,只能跳出當前循環(只能跳出一層循環)
continue: 直接開始下一輪循環
表達式的真假問題:
a>b a>b&&b>c 類似於這樣的關係表達式或者邏輯表達式,結果只有兩個:true false值就是1和0
反過來説 0是假,非零是真
int n =0;
while(n<=100)
{
printf("%d",n);
n++;
}
n =0;
while(101-n)
{
printf("%d",n);
n++;
}
0.2 預處理命令
0.2.1 #include
用於包含頭文件的 <>用於編譯器自帶的 “”用於自己寫的頭文件
0.2.2 #define
無參宏
0.3 二維數組
可以看成是多個1維數組
#include <stdio.h>
int main()
{
//二維數組的定義和初始化
//假如方括號內的元素不夠,後面就都初始化為0
int arrTest1[3][4] = { 1,2,3,4,5,6,7 };
// 1 2 3 4
// 5 6 7 0
// 0 0 0 0
int arrTest2[3][4] = { {1,2},{3,4},{5,6} };
// 1 2 0 0
// 3 4 0 0
// 5 6 0 0
int arrTest3[][5] = { 1,2,3,4,5,6,7,8,9,10,11 };
//等價於int arrTest[3][5] = {1,2,3,4,5,6,7,8,9,10,11};
//1 2 3 4 5
//6 7 8 9 10
//11 0 0 0 0
return 0;
}
什麼時候會使用二維數組:
在一組數據中,還要再次分組的時候,需要使用二維數組。
假如有一個二維數組,如何遍歷這個二維數組
1. 函數
複習:
system 執行一條CMD命令
printf 格式化輸出
scanf_s 格式化輸入
getchar 獲取一個字符
putchar 輸出一個字符
_getch 無回顯的獲取一個字符
strlen 求字符長度
strcat_s 拼接字符串
strcpy_s 拷貝字符串
strcmp 比較字符串
1.1 函數的基本定義格式
返回值類型 函數名稱(形參列表)
{
函數的語句;
return 返回值;
}
函數名稱:是我們自己定義的名字,名字的規則和變量名是一致:字母數字下劃線 數字不能開頭,不能使用關鍵字
返回值類型:一個函數如果需要返回一個數據作為整個函數的結果,那麼就應該定義返回值類型。
return的作用:
a. 結束函數
b. 返回給函數的調用的位置一個數值,這個數值就是函數的結果。返回的數值需要和返回值類型匹配。
形參列表:我們要實現這個函數,需要什麼參數,在這裏規定好類型和參數個數
設計一個函數原則:
1.我們需要明確這個函數的功能是什麼???一般情況下,函數的功能越單一越好,一個函數最好只解決一個問題。
2.明確了函數功能之後,需要明確需要哪些前置的數據。(我們應該如何去設計參數)
3.當功能實現完畢之後,要如何將結果告知調用者
a. 返回值
b. 也可以通過參數,傳出數據
c. 也可以修改全局變量
d. 也可以將結果寫入到一個文件中
e. 也可以在屏幕上輸出一個結果(非常少的)
1.2 函數的使用場景
#include <stdio.h>
int main()
{
//我們輸入3個同學的名字
//輸出3個同學名字字符數量之和
char szName1[20] = {};
char szName2[20] = {};
char szName3[20] = {};
printf("請輸入名字:");
scanf_s("%s", szName1,20);
printf("請輸入名字:");
scanf_s("%s", szName2,20);
printf("請輸入名字:");
scanf_s("%s", szName3,20);
int n1 = 0;
while (szName1[n1]!=0)
{
n1++;
}
int n2 = 0;
while (szName2[n2] != 0)
{
n2++;
}
int n3 = 0;
while (szName3[n3] != 0)
{
n3++;
}
printf("3個同學的名字長度之和為%d", n1 + n2 + n3);
return 0;
以上解決了問題,但是求名字長度的代碼,寫了3遍,萬一100個學生,那重複代碼就太多了。
這個時候就應該使用函數,可以少些重複代碼.
#include <stdio.h>
//1.明確功能:寫一個求字符數組中字符串長度的函數
//2.明確參數:字符數組
//3.明確結果如何告知調用者:通過返回值就可以 返回值類型就應該是int
//返回值類型 函數名
//{
// 具體的函數語句
// return 返回值;
//}
int GetStrLenth(char szBuf[20])
{
int n2 = 0;
while (szBuf[n2] != 0)
{
n2++;
}
return n2;
}
int main()
{
//我們輸入3個同學的名字
//輸出3個同學名字字符數量之和
char szName1[20] = {};
char szName2[20] = {};
char szName3[20] = {};
printf("請輸入名字:");
scanf_s("%s", szName1, 20);
printf("請輸入名字:");
scanf_s("%s", szName2, 20);
printf("請輸入名字:");
scanf_s("%s", szName3, 20);
//使用函數的好處1:
//定義完函數之後,調用的時候就只需要寫函數名和參數,就能夠使用這個功能了
//不需要寫很多重複代碼
//代碼的 【複用性】就提高了
//使用函數的好處2:
//我們給這段代碼起了名字,在閲讀代碼的時候,根據名字能夠更好的理解代碼邏輯
//提高了 代碼的 【可讀性】
int n1 = GetStrLenth(szName1);
int n2 = GetStrLenth(szName2);
int n3 = GetStrLenth(szName3);
printf("3個同學的名字長度之和為%d", n1 + n2 + n3);
return 0;
1.3 關於形參和實參的問題
形參是定義函數時候,用於規定參數類型的
實參是調用函數的時候,真實傳遞的參數。
1.4 需要注意的地方
1.形參的改變,不會影響實參的值
2.如果函數的定義在調用的下面,此時編譯器就不會識別這個函數,我們需要在調用之前加上函數的聲明。
練習:
實現一個函數,能夠得到兩個整數中的較大值。
#include <stdio.h>
int GetMax(int a, int b);
int main()
{
int n = 10;
int m = 20;
int c = GetMax(n, m);
printf("較大值為%d", c);
return 0;
}
int GetMax(int a, int b)
{
if (a > b)
{
return a;
}
else
{
return b;
}
}
2. 全局變量與局部變量
2.1 作用域
標識符 起作用的 代碼範圍
局部變量:定義在函數內部的變量,只在函數內部起作用,準確的説,是在定義它的花括號內起作用。
全局變量:定義在函數外部的變量,整個文件中的任何函數,都能訪問到
2.2 局部變量和全局變量的特點
例子1,2:局部變量是在定義它的花括號內起作用。
例子3:小作用域覆蓋大的
#include <stdio.h>
int main()
{
int n = 100;
if (n>5)
{
//同名的時候,小作用域會覆蓋大作用域
int n = 50;
printf("%d", n);//這個位置輸出的是50
}
printf("%d", n);//這個位置輸出的是100
return 0;
}
總結:
1.大家使用同一個全局變量
2.局部變量和全局的同名了,這就是兩個變量了,在定義局部變量的函數中,使用的是局部變量
3.全局變量如果定義在了下面,上面使用的時候,就應該加聲明。
#include <stdio.h>
//全局變量如果不初始化,默認就是0
//局部變量不初始化,就是隨機值
extern int g_nNum;
void Fun1()
{
g_nNum = 100;
}
void Fun2()
{
int g_nNum = 30;
Fun1();
g_nNum *= 2;
}
int main()
{
printf("%d", g_nNum);
Fun2();
printf("%d", g_nNum);
return 0;
}
int g_nNum = 0;
2.3 static類型的局部變量
#include <stdio.h>
void Fun1()
{
int nNum = 0;
nNum++;
printf("%d ", nNum);
}
void Fun2()
{
//這裏就定義了一個靜態局部變量
static int nNum = 0;
nNum++;
printf("%d ", nNum);
}
int main()
{
for (int i = 0; i < 10; i++)
{
Fun1();
}
printf("\n");
for (int i = 0; i < 10; i++)
{
Fun2();
}
return 0;
}
普通的局部變量,在離開作用域的時候,就會被銷燬掉,再次進入函數,局部變量會重新建立。
靜態局部變量,再離開作用域也不銷燬。下次進入函數,直接使用上一次的值。
2.4 const類型的變量
const被用於定義 不能修改的變量 (常量)
2.5 什麼是形參?什麼是實參?
什麼是形參?
形參全稱叫做“形式參數”,也是一個虛擬的參數,在定義方法的時候使用的參數,形參是方法被調用時用於接收實參值的變量。
什麼是實參?
實參全稱叫做“實際參數”,顧名思義就是實際存在的參數,實參可以是常量、變量、表達式、類等,實參必須要有確定的值。
總結:形參與實參的類型、個數是要一一對應的
我們看下下面這段代碼,來更加深入的瞭解什麼是形參?什麼是實參?
public class MethodTest2 {
public static void main(String[] args) {
sum(4,6);//這裏邊的4,6就是實參
}
public static void sum(int a,int b){
//sum(int a,int b) 這裏邊的int a,int b 就是形參
//它們的類型和傳進來的4,6的類型和個數都是一一對應的
//這裏邊的a就是4 b就是6
int c = a + b;//相當於int c = 4 + 6;
System.out.println("a + b = " + c);
//結果:a+b=10
}
}
C/C++程序的工程管理方式
3.1 基本組織方式
一個工程由多個文件組成
.cpp中寫 函數與全局變量的定義。
.h中 寫聲明
在使用的位置,包含頭文件即可。
千萬不要在.h中寫定義
3.2 static修飾全局變量和函數的作用
4. 指針
三步:
定義指針變量
給指針變量賦值
解引用
#include <stdio.h>
int main()
{
//1. 定義指針變量
int* p1 = nullptr;//定義了一個整型指針 變量 nullptr是0
char* p2 = nullptr;//定義了一個字符型指針
//2. 給指針變量賦值
//指針應該存儲的是地址
int nNum1 = 100;
int nNum2 = 50;
//p存儲了nNum1的地址
//p存儲了誰的地址,我們就説p指向了誰
p1 = &nNum1;
//3. 解引用
//通過指針間接的訪問到,它所指向的位置
printf("%d\n", nNum1);
printf("%d\n", *p1);
*p1 = 500;//*p1此時就相當於是nNum1
printf("%d\n", nNum1);
printf("%d\n", *p1);
p1 = &nNum2;
*p1 = 300;
printf("%d\n", nNum1);
printf("%d\n", nNum2);
return 0;
}
4.2 應用場景
4.2.1 場景1 在函數內部修改到函數外部的變量
#include <stdio.h>
//用一個函數,交換兩個變量的值
void swap1(int a, int b)
{
int n = a;
a = b;
b = n;
}
void swap2(int* p1,int * p2)
{
int n = *p1;
*p1 = *p2;
*p2 = n;
}
int main()
{
int n = 10;
int m = 20;
swap2(&n, &m);
printf("%d %d", n, m);
return 0;
}
以上代碼,我們通過指針修改了外部的數據,能不能算形參改變了實參呢???
不能。為什麼????
因為 實參是變量的地址。變量的地址並沒有發生改變。
4.2.2 場景2 指針和一維數組 語法基本通用
補充幾道指針計算練習題
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));
//2,5
system("pause");
return 0;
}
題目分析:數組名a表示數組首元素的地址,(&a+1)表示將整個數組的地址加一,(int)(&a+1)表示將(&a+1)強制類型轉換為int類型。
所以本題的結果為: