#mark- 01-二維數(shù)組基本概念
//問題:什么是二維數(shù)組?二維數(shù)組的格式?二維數(shù)組如何存儲(chǔ)?二維數(shù)組是如何遍歷?
1.二維數(shù)組: 數(shù)組中的每一個(gè)元素又是一個(gè)數(shù)組, 那么這個(gè)數(shù)組就稱之為二維數(shù)組
2.二維數(shù)組格式:
元素類型 數(shù)組名稱[一維數(shù)組的個(gè)數(shù)][每個(gè)一維數(shù)組的元素個(gè)數(shù)];
元素類型 數(shù)組名稱[行數(shù)][列數(shù)];
元素類型: 說明二維數(shù)組中每個(gè)一維數(shù)組存儲(chǔ)什么類型的數(shù)據(jù)
一維數(shù)組的個(gè)數(shù): 說明二維數(shù)組有多少個(gè)元素
每個(gè)一維數(shù)組的元素個(gè)數(shù) :? 說明二維數(shù)組中每一個(gè)一維數(shù)組的元素個(gè)數(shù)
3.遍歷二維數(shù)組
// 思路: 1.取出二維數(shù)組的每一個(gè)元素(取出二維數(shù)組中的一維數(shù)組)
//? ? ? 2.遍歷一維數(shù)組
for (int i = 0; i < 2; i++) { // 0 , 1
for (int j = 0; j < 3; j++) { // 0 , 1 , 2
printf("name[%i][%i] = %c\n", i, j, names[i][j]);
}
}
#mark- 02-二維數(shù)組注意點(diǎn)
//問題:二維數(shù)組如何初始化?
二維數(shù)組的多種初始化方式
// 1.定義的同時(shí)初始化
int names[2][3] =
{
{'l', 'n', 'j'},
{'x', 'm', 'g'}
};
// 2.先定義再初始化
int names2[2][3];
names2[0][0] = 'l';
names2[0][1] = 'n';
names2[0][2] = 'j';
names2[1][0] = 'x';
names2[1][1] = 'm';
names2[1][2] = 'g';
// 3.完全初始化
int names3[2][3] =
{
{'l', 'n', 'j'},
{'x', 'm', 'g'}
};
// 4.不完全初始化
int names4[2][3] =
{
{'l', 'n'},
};
// 5.省略元素個(gè)數(shù)的兩種寫法
// 明確的告訴二維數(shù)組, 我們有2個(gè)一維數(shù)組
char names5[2][3] =
{
'l', 'n', 'j',
'x', 'm', 'g'
};
// 沒有告訴二維數(shù)組我們有幾個(gè)一維數(shù)組
// 如果在"定義的同時(shí)"進(jìn)行初始化, 那么一位數(shù)組的個(gè)數(shù)可以省略 \
系統(tǒng)會(huì)自動(dòng)根據(jù)每一個(gè)一維數(shù)組能夠存放多少個(gè)元素, 自動(dòng)根據(jù)初始化的值推斷出二維數(shù)組中一共有多少個(gè)元素(多少個(gè)一維數(shù)組)
char names6[][3] =
{
'l', 'n', 'j',
'x', 'm', 'g',
'n', 'b'
};
// 6.錯(cuò)誤寫法
// 注意點(diǎn): 每個(gè)一維數(shù)組的元素個(gè)數(shù)不能省略
/*
int names7[2][] =
{
{'l', 'n', 'j'},
{'x', 'm', 'g'}
};
*/
/*
// 搞不清楚應(yīng)該分配多大的存儲(chǔ)空間, 以及搞不清楚應(yīng)該把哪些數(shù)據(jù)賦值給第一個(gè)數(shù)組, 以及哪些數(shù)據(jù)賦值給第二個(gè)數(shù)組
int names7[2][] =
{
'l', 'n', 'j',
'x', 'm', 'g'
};
*/
#mark- 03-二維數(shù)組和函數(shù)
//問題:二維數(shù)組作為函數(shù)參數(shù)傳遞?
//數(shù)組傳遞,值傳遞的區(qū)別
//二維數(shù)組可以省略一維數(shù)組的個(gè)數(shù),不可省略一維數(shù)組有多少個(gè)元素
1.二維數(shù)組名稱作為函數(shù)參數(shù)傳遞, 是傳遞的地址
change2(names);
void change2(char values[2][3])
{
values[0][1] = 'w';
printf("我執(zhí)行了\n");
}
2.// 以后只要看到函數(shù)的參數(shù)是一個(gè)數(shù)組, 那么就是地址傳遞
// 在函數(shù)中修改形參的值會(huì)影響到參數(shù)
names[0] == 一維數(shù)組
change3(names[0]);
void change3(char values[])
{
values[0] = 'Q';
printf("我執(zhí)行了\n");
}
3.// 基本數(shù)據(jù)類型
names[0][0] == 一維數(shù)組的一個(gè)元素 == 值
change4(names[0][0]);
void change4(char value)
{
value = 'E';
printf("我執(zhí)行了\n");
}
#mark- 04-字符串基本概念
//問題:什么是字符串?如何初始化字符串?輸出字符串?
//問題2:%s的原理?
1.用雙引號(hào)引起來的就是字符串
2.字符串變量和普通的字符數(shù)組的區(qū)別
char str[] = "lnj"; // 字符串變量 l n j \0
// 字符數(shù)組 , 這個(gè)并不是字符串, 而是字符數(shù)組
char charValues[] = {'l', 'n', 'j'};
3.//C語言規(guī)定, 字符串必須以\0結(jié)尾(作為字符串的結(jié)束符號(hào)), 所以字符串變量的元素個(gè)數(shù)比字符數(shù)組的元素個(gè)數(shù)多一個(gè) \0
4.//字符串變量輸出的的原理
%s的原理, 從傳入的"地址"開始逐個(gè)取出, 直到遇到"\0"為止
5.注意:字符串以\0結(jié)尾, 沒有\(zhòng)0就不是字符串
6.//字符串的本質(zhì)就是數(shù)組
char str6[] = "lnj";
str6[1] = 'y';
printf("%s", str6);
#mark- 05-子符串常用方法1
//問題:如何輸出字符串?
//問題1:printf和puts 函數(shù)的區(qū)別
1.printf和puts 函數(shù)的區(qū)別
printf函數(shù)
弊端 : 如果想要換行, 必須加上\n
優(yōu)點(diǎn) : 可以自定義格式化需要輸出的字符串, 也就是可以按照我們需要的格式來輸出
puts函數(shù)
優(yōu)點(diǎn): 可以自動(dòng)換行
缺點(diǎn): 不可以自定義格式, 只能原樣輸出
//問題2:利用scanf接收字符串的有什么注意點(diǎn)?
2.輸入字符串
1)利用scanf接收字符串的注意點(diǎn)
scanf接收字符串, 會(huì)以空格 , tab, 回車作為結(jié)束符號(hào), 也就是說利用scanf接收字符串時(shí), 字符串中不能出現(xiàn)空格, tab, 回車
2)利用gets接收字符串優(yōu)點(diǎn)
優(yōu)點(diǎn): 如果利用gets接收字符串 , 可以在字符串中輸入空格, tab
//問題3:如何計(jì)算字符串長度?
3.使用strlen 計(jì)算字符串長度
strlen的原理: 從傳入的地址開始逐個(gè)取出字符串, 每取出一個(gè)就讓計(jì)數(shù)器+1. 直到遇到\0為止
#mark- 06-字符串常用方法2
//問題:字符串如何拼接,拷貝,比較?
1.字符串拼接原理
strcat()
// 原理 : 首先遍歷第一個(gè)字符串,直到遇到\0為止, 然后取出第二個(gè)字符串中的字符, 從\0的位置開始添加, 添加完畢之后再在最后添加一個(gè)\0
2.字符串拷貝原理
strcpy()
逐個(gè)替換, 拷貝了幾個(gè)就替換幾個(gè)
//strcpy函數(shù)會(huì)將源的數(shù)據(jù)拷貝到目標(biāo)中, 并且會(huì)覆蓋掉目標(biāo)中原有的數(shù)據(jù)
// 目標(biāo)的容積必須能夠存放拷貝的數(shù)據(jù), 如果容積不夠會(huì)報(bào)錯(cuò)
3.字符串比較
strcmp()
// strcmp的原理: 取出字符串中的每一個(gè)字符進(jìn)行逐個(gè)比較, 如果發(fā)現(xiàn)不相等就不會(huì)繼續(xù)往下比較
#mark- 07-字符串練習(xí)
// 編寫一個(gè)函數(shù)char_contains(char str[],char key), 如果字符串str中包含字符key則返回?cái)?shù)值1,否則返回?cái)?shù)值0
// 給你一個(gè)字符串和一個(gè)key, 要求從字符串中找出key, 如果找到就返回1沒有找到就返回0
#mark- 08-字符串?dāng)?shù)組
//問題:什么是字符串?dāng)?shù)組?
// 如果想存儲(chǔ)一堆字符串那么可以使用字符串?dāng)?shù)組
// 說白了字符串?dāng)?shù)組就是二維數(shù)組
#mark- 09-指針基本概念
//問題:什么是指針?格式?保存的是什么數(shù)據(jù)?指針有什么作用?
指針就是專門用于保存地址的
1.定義指針變量
普通變量:
數(shù)據(jù)類型 變量名稱;
指針變量:
數(shù)據(jù)類型 * 變量名稱;
數(shù)據(jù)類型 : 說明將來指針變量能夠保存什么類型的變量的地址
注意: 指針變量是什么類型, 那么將來就只能保存什么類型變量的地址,
例如: 指針變量是int類型, 那么將來就只能保存int類型變量的地址
* : 沒有任何特殊含義, 僅僅是為了標(biāo)示這是一個(gè)指針變量
變量名稱 : 用于區(qū)分不同的變量
2.指針 , 在64位編譯器下占用8個(gè)字節(jié)
3.注意:指針變量前的*號(hào)代表訪問指針變量指向的那一塊存儲(chǔ)空間
4.指針定義時(shí),一定要給一個(gè)地址
int a = 10;
float b = 9.9;
int *p = &a;//指針定義時(shí),初始化只能是地址
*p = 22;//指針定義后,給帶星指針賦值,只能是數(shù)值
p = &b; //給不帶星指針賦值,一定是地址
printf("a = %d, b = %d", a, *p);
#mark- 10-指針練習(xí)1
//問題:如何使用指針交換兩個(gè)變量的值?
// 定義一個(gè)函數(shù)交換兩個(gè)變量的值
注意:畫圖分析內(nèi)存
和數(shù)組進(jìn)行對(duì)比
void swap(int *v1, int *v2)
// int *v1 = &a, int *v2 = &b; v1 = 0ffc13 v2 = 0ffc9
// *v1 == a? *v2 == b
{
int temp = *v1; // int temp = 0ffc13
*v1 = *v2;
*v2 = temp;
}
#mark- 11-指針練習(xí)2
//問題:如何通過指針修改函數(shù)外部變量?
// 要求:定義一個(gè)函數(shù), 傳遞三個(gè)值, 返回這三個(gè)值得和,差,平局值
注意:畫圖分析
int demo(int v1, int v2, int v3, int *p1, int *p2)
{
int sum = v1 + v2 + v3;
*p1 = sum;
int m = v1 - v2 - v3;
*p2 = m;
int average = sum / 3;
return average;
}
#mark- 12-指針注意點(diǎn)
//問題:指針的幾個(gè)注意點(diǎn)?
// 1.指針只能保存地址
int *p = 200;
printf("%i\n", *p);
// 2.同一個(gè)變量可以有多個(gè)指針指向它
int num = 10;
int *p = #
// *p == num
//? ? num = 55;
*p = 55;
int *p1 = p;
*p1 = 100;
int *p2 = #
printf("%i\n", *p);
// 3.指針的指向可以修改
int a = 10;
int b = 5;
int *p = &a;
*p = 88;
p = &b;
*p = 44;
printf("%i\n", a);
printf("%i\n", b);
// 4.不要訪問野指針
// 沒有賦值的指針, 我們稱之為野指針
//? ? int *p;
int *p = NULL; // 0
printf("%i\n", *p);
// 5.指針類型是什么類型, 就只能指向什么類型的數(shù)據(jù)
int num = 10;
char charValue = 'l';
double doubleValue = 9.9;
//? ? int *p = #
//? ? int *p = &charValue;
//? ? int *p = &doubleValue;
double *p = &doubleValue;
printf("%lf\n", *p);
#mark- 13-多級(jí)指針
//問題:如何使用多級(jí)指針?
多級(jí)指針的操作, 最簡單的方式, 就是通過幾顆星來存儲(chǔ), 就通過幾顆星來訪問
還有一種方式就是畫圖, 看圖片中有幾個(gè)箭頭, 有幾個(gè)簡單就用幾顆星來訪問
#mark- 14-指針為什么要分類型
//指針為什么要分類型?
// 因?yàn)楫?dāng)我們利用指針去取值的時(shí)候, 系統(tǒng)就會(huì)自動(dòng)根據(jù)指針的類型來確定應(yīng)該取對(duì)少個(gè)字節(jié)中的值