指針
1.指針
指針 就是地址
(地址就是內存單元的編號)
指針變量?
(結合語境)?
eg:
定義一個指針
指針這一類數據 --- 數據類型 --- 指針類型?
(1).指針 是什么?
(2).指針類型?
? ?int a; //int數據類型 a是int型變量?
//a的空間 想來存儲 整型數據?
?? ? ?
2.指針的定義?
基類型 * 指針變量名;
int a = 10;
int *p = &a;
指針變量本身 ? ? ? // p ? ? ?
指針變量指向的目標 ?// a
begin ? //指針變量本身 --- 放的是一個地址?
*begin ?//基類型 ?
3.指針間接訪問?
通過指針來使用內存空間?
*p?
step1:拿p中的值 到內存中定位?
step2:從定位處開始,偏移sizeof(基類型)大小一塊空間
step3:將這塊空間當做一個基類型(變量/數據)來看?
*p <=> a
4. 指針用途?
函數帶出多個參數?
操作硬件?
函數參數?
核心:
被調? ? ? ? 修改? ? ? ? ? 主調?
實現的兩個要素:
a.要修改誰,傳誰的地址 ?//拿到地址 --只是知道在哪兒呢??
b.被調函數中,要有對應*p這種運算 //如何用-- 用?
5.指針使用數組?
整型一維數組?
(1).指針運算?
指針 + 1 ?//
指針 相減 ---減出來的 數據是個整型數據?
差了多少基類型
指針 關系運算?
(2).指針能夠操作數組?
a.數組的特點
b.只需要獲得首元素地址即可?
指針 + 字符型數組
char s[10] = "hello"; ?//字符串 --- 存放在棧空間?
// 堆區 ?也可以放?
// 全局?
// 字符串常量區
char *p = "hello"; //字符串常量 --沒有數組名的數組 ??? ??? ??? ??? ??? ? ??
char *p = s;
s[0] ? //char?
&s[0] ?//char *?
說明:
指針代表的位置 ---地址的含義 ---說明在哪里
先用對應的空間 --- *p?
區分(考點)
char s[] = "hello"; ?//s本身的空間在棧上 ,"hello"本身是字符串常量,存放字符串常量區
//用字符串常量區中 "hello" 初始化了 棧上s的空間
//注意: s[0] = 'h'; (正確) --- 棧上的空間可讀可寫?? ???
? ? ? ? ? ? ? ? ? ? ? ?有兩個“hello”,一個在常量區,一個在棧上
char *s = "hello"; ? //s本身的空間在棧上,s是char*的指針變量,用來存放一個 char *的地址?
//"hello"本身是字符串常量,存放字符串常量區
//"hello"字符串都是按字符數組的方式存儲的?
//相當于是一個匿名數組 ---- 獲得的還是首元素的地址
//注意: s[0] = 'h'; (錯誤) ---常量區空間不能修改 ?? ??? ??
? ??? ??? ??? ? ??
const
const char * s = "hello";
int a; ? ? ? ?//變量 ?--可讀可寫?
const int a; ?//只讀變量 -- 只讀
const 本身的作用 : 限定為只讀?
?const char * s; //const 用來修飾基類型 ?--- 限定基類型為只讀 ---只是說,不能通過*p 修改,相當于限定了*p為只讀
char const * s; //const 用來修飾基類型 ?--- 限定基類型為只讀?
char const *s
(等價于?const char *s
)
含義:指向常量字符的指針
const
?修飾的是?char
,表示指針?s
?所指向的字符是?不可修改的(常量)。- 但指針?
s
?本身是?可以改變指向的(可以指向其他字符)。
?char * const s; ?//const 用來修飾指針變量本身 --- 將指針變量本身限定為只讀---指針變量本身不能被修改?
?const char const *s; //指針變量 本身不能被修改?
//*s 也不能被修改 ??
char *const s
含義:指向字符的常量指針
const
?修飾的是指針?s
?本身,表示指針?s
?的?指向是固定的(不能改變)。- 但指針?
s
?所指向的字符是?可以修改的。
?const 修飾指針的時候:
區分
修飾指針變量本身?
修飾基類型?
?規則:
距離誰近 就修飾誰
就近原則?
說明:
1.const 可以將運行錯誤提前?
2.const 修飾函數的形參?
a.提高了參數的適用性?
//數組名?
//char *
//const char *
b.防止函數誤操作?
建議,能寫成const 都寫成const
void Puts(char *s)
void Puts(const char *s) ?
int puts(const char *s); //const 什么時候,如果函數中只是用數據,而不涉及修改操作,一般都建議寫成const?
練習:
strlen?
int Strlen(const char *s)
{
}
練習:
strcpy?
char *Strcpy(char *dest, const char *src)
{ ? ??
char *ret = dest;
拷貝?
return ret;
}
? ?返回值 ?返回值 dest?
char *Strncpy(char *dest, const char *src, size_t n)
{
char *ret = dest;
//始終拷貝了n次?
// n < 字符串長度 那么n次拷完 就結束?
// n > 字符串長度 字符串拷貝完成, n剩余的次數還要拷貝 --- 拷貝的是 0
return ret;
}
n 表示 將src的前n個字符拷貝到dest中?
將前n個字符拷貝到dest中,但是如果前n個中沒有 '\0' 那dest中也不會后?
n 大于 字符串長度 保證n次 拷貝夠?
剩余的次數 通通拷貝 0
練習:
strcat?
char *Strcat(char *dest, const char *src)
{ ? ?
//1.定位到dest 的 '\0'位置?
//2.拷貝?
//3.保證 dest 是字符串 ? ??
}
//將src中前n個字符拼接到dest中
char *strncat(char *dest, const char *src, size_t n);
{
//1.定位到dest 的 '\0'位置?
//2.拷貝?
//n < strlen(src) ?前n字符拼接完 就結束 --- 最后保證是字符串 --dest最后要加'\0'
//n > strlen(src) ?將src拼接完成 就結束 --- 最后保證是字符串 --dest最后要加'\0'
//3.保證 dest 是字符串 ? ?
}
練習:
strcmp
int Strcmp(const char *s1, const char *s2)
{
從左到右 逐個比?
遇到不同的 或者 '\0'
}
//表示 比較 s1 和 s2 前n個字符?
//hello
//help
int Strncmp(const char *s1, const char *s2, size_t n)
{
}
小結:
1.語法 --- 指針要操作數組 只需要獲得首元素的地址?
2.字符串 --- 字符串有結束標志?
3.棧上的字符串
常量區中的字符串?
指針 + 二維數組?
指針 + 整型二維?
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
指針要操作數組 只需要獲得首元素的地址?
? * p?
二維數組的本質:
int[4] a[3];? ? ? ? ? ?//元素類型 int[4] //a[0]
二維數組中首元素?
a[0]? ? ? ? ? ? ?// 首元素的數據類型 ---int[4]?
&a[0]? ? ? ? ? ? ? ? ?// int[4] * ? //指針類型?
int[4] *p; //理解沒問題?
int (*p) [4]; //表示定義了一個指針 指向int[4]這種類型?
//指向的目標是個數組類型 --- 數組指針
?? ??? ??? ? ?
*(p+1) <=> a[1] //表示可以用一整行的空間 ?
//a[1] <=> *(p+1)
//a[1] 相當于是 內部的 一整行數組的 數組名 (*(p+1))
// ?數組名 代表的類型 ?整個數組大小 ? ?// int[4]這種類型
// ?數組名 代表的值 ? 首元素的地址 ? ?// &a[1][0]
// ? ? ? 地址的類型 --- int *
*(p+1) ?//代表 ?第 1 行的首元素的地址?
*(p+1) + 1 ? // 第1行 第1列 元素的地址?
*(*(p+1) + 1) // ?第1行 第1列 的 元素 //變量?
二維數組 ,通過指針訪問數組元素:
p+i ? ? ??? ??? ?//第i行的 地址?
*(p+i) ? ??? ??? ?//第i行的 首元素 的地址 ?--- 內部的一維數組的數組名?
*(p+i)+j ??? ??? ?//第i行的 第j列 元素的地址
*(*(p+i)+j) ??? ?//第i行 第j列 的元素
//訪問到二維數組元素的方式:
*(*(p+i)+j)?
*(p[i]+j)
*(*(p++)+j)
*(*(a++)+j) //數組名 --- 代表首元素地址 --- 地址常量 a 是個常量, a++ 不能做?
*(a[i]+j)?
-----------------------------------------------------------------
練習:
實現一個函數 找出數組中最大值?
指針 + 字符二維數組?
char s[3][10] = {"hello","world","china"};
char (*p)[10] = s;
練習:
實現一個輸入函數,可以從鍵盤輸入字符串?
void scanfStr(char (*s)[10],int row)
{
}
練習:
//找最大值?
作業:
1. 編寫一個程序實現功能:
將字符串”Computer Science”賦給一個字符數組,
然后從第一個字母開始間隔的輸出該字符串,用指針完成。
"Cmue cec"
2. 編寫程序實現單詞的倒置
"how are you" -> "you are how"
//char s1[] = "how";
3. 封裝一個函數,統計一個字符串中出現指定單詞的個數
int WordCnt(char *pStr, char *pWord)
{
}
"fdsahelfdashellofdashellofdashellofdashellohello"
"hello"