当前位置: 首页 > news >正文

玳瑁的嵌入式日记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"

http://www.lryc.cn/news/612093.html

相关文章:

  • 【运维进阶】DHCP服务配置和DNS域名解析
  • TypeScript ActionScript
  • 浅谈RNN被Transformer 取代的必然性
  • Kotlin Native调用C curl
  • Uniapp生物识别(SOTER)
  • 【第5话:相机模型1】针孔相机、鱼眼相机模型的介绍及其在自动驾驶中的作用及使用方法
  • 第二十六天(数据结构:树(补充版程序请看下一篇))
  • 数字图像处理(冈萨雷斯)第三版:第四章——空间滤波与频域滤波(平滑与锐化)——主要内容和重点
  • 【PHP 抽象类完全指南(含 PHP 8.4 新特性)】
  • 02.【数据结构-C语言】顺序表(线性表概念、顺序表实现:增删查、前向声明、顺序表实现通讯录项目:增删改查、通讯录数据导入及保存到本地文件)
  • Linux操作系统启动项相关研究与总结
  • Redis面试精讲 Day 12:Redis Sentinel哨兵机制详解
  • 深度学习(pytorch版)前言:环境安装和书籍框架介绍
  • 单变量单步时序预测:CNN-GRU卷积神经网络结合门控循环单元
  • Linux系统编程——环境变量、命令行参数
  • mysql8.0主从节点克隆
  • Numpy科学计算与数据分析:Numpy入门之多平台安装与基础环境配置
  • 用NAS如何远程访问:详细教程与实用技巧
  • 强强联合:OpenAI正式登陆AWS!
  • 【motion】标签体系设计与检索 1:HumanML3D 和 KIT Motion-Language(KITML)
  • 《Vue 3与Element Plus构建多语后台的深层架构》
  • 导入Excel打印
  • GEAR:一种高效的 KV Cache 压缩方法,用于几乎无损的大语言模型生成式推理
  • 云手机对于网络游戏的作用
  • linux下的串口通信原理及编程实例
  • 【完整源码+数据集+部署教程】耳镜耳部疾病分类系统源码和数据集:改进yolo11-HSFPN
  • Centos 安装 redis
  • 理解生成统一模型技术调研报告
  • 北京-4年功能测试2年空窗-报培训班学测开-第六十九天-投简历第一天-从兴奋到害怕
  • GPT-OSS-20B vs Qwen3-14B 全面对比测试