玳瑁的嵌入式日记D13-0806(C语言)
指针
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"