学习指针第三日

const

const //只读

const int a; //a 此时是一个只读的变量

1.四种用法

int a = 10;

//int *p = &a;

const int *p = &a; //const限定是 基类型

//表示不能通过 *p 的方式 修改基类型数据

int const *p = &a; //const限定是 基类型

//表示不能通过 *p 的方式 修改基类型数据

int * const p = &a; //const限定是 指针变量p

//表示将p限定位只读

//表示p不能被修改

const int * const p = &a; //基类型和指针变量 都被限定为只读

// p = &b; //不能修改

//*p = b; //不能修改

应用:

1.如果 不想 通过*p方式改变基类型对应的数据

const int *p = &a;

int const *p = &a;

2.如果 指针变量p 定义好后,不想再指向别的变量

int * const p = &a;

原则:

就近原则 //const 离谁近 就限定谁

2.void Puts(const char *s)中使用const

注意:

1.形参 设计为 const char *

目的,

防止函数中的误操作

2.好处

(1).提前发现问题

将运行时问题,提前到编译时

(2).const char *

可以接收

char *

const char *

实参:

可以 数组名

可以 指针变量 char *p //const char *p

可以 直接是一个字符串常量

提高参数的适用性

注意:

能写成const的 都写const

指针+字符串

字符串 // 在c语言中是按照字符数组的形式存储

// 字符串常量 --- 存储在字符串常量区

处理字符串:
char s = "hello"; //表示 在栈上开辟一块空间,用字符串常量中的 "hello"
//进行初始化
const char *p = "hello"; //表示 p指向了 字符串常量区中的 "hello"
//因为 是指向了字符串常量区
//只能做读取操作,不能修改

memcpy函数

void *memcpy(void *dest, const void *src, size_t n)

{

//一个字节一个字节拷贝

}

void *

//空类型的指针 --- 万能指针

//可以接收任意类型的指针

注意:

1.注意,如果用 空类型指针 进行 间接运算

必须 转换成 有明确类型的指针

cs 复制代码
void Memcpy(void *dest,const void *src,size_t n)  //n传的是字节数
{
	char *p = dest;
	const char *q = src;
	while (n)
	{
		*p = *q;
		p++;
		q++;
		--n;
	}
}

char *Strncpy(char *dest, const char *src, size_t n)

{

//1.始终拷贝了n下

//1. 拷贝

'\0' && n

//2. 考虑n

n有没有结束

完成剩余的次数的拷贝

拷贝过去的数据 '\0'

}

cs 复制代码
char * Strncpy(char *dest,const char *src,size_t n)
{
	char *ret = dest;

	while ( n!=0 &&*src != '\0')
	{
		*dest = *src;
		++dest;
		++src;
		--n;
	}

	while(n)
	{
		*dest = '\0';
		++dest;
		--n;
	}

	return ret;
}

char *Strncat(char *dest, const char *src, size_t n)

{

//1.可以指定 n

//如果 src 长度 > n

就将前n个字符拼接过去

//如果 src 长度 < n

直接将src字符串拼接过去

最终 一定要保证 dest是一个字符串 '\0'

}

cs 复制代码
char * Strcat(char *dest,const char *src)
{
	char *ret = dest;

	while (*dest != '\0')
		++dest;

	while (*src != '\0')
	{
		*dest = *src;
		++dest;
		++src;
	}

	*dest = '\0';

	return ret;
}

char * Strncat(char *dest,const char *src,int n)
{
	char *ret = dest;

	while (*dest != '\0')
		++dest;

	while ( n && *src != '\0')
	{
		*dest = *src;
		++dest;
		++src;
		--n;
	}

	*dest = '\0';

	return ret;
}

int strncmp(const char *s1, const char *s2, size_t n);

//表示值比较 s1 和 s2 中前n个字符

{

多了一个比较限制条件 n

}

cs 复制代码
int Strcmp(const char *s1,const char *s2)
{
	while (*s1==*s2 && *s1!='\0' && *s2!='\0')
	{
		++s1;
		++s2;
	}

	return *s1 - *s2;
}

int Strncmp(const char *s1,const char *s2,size_t n)
{
	//n = 3 s1 s2 
	//n = 2 s1+1 s2+1
	//n = 1 s1+2 s2+2 
	//      s1+3 s2+3 //n = 0 
	while ( n > 1&&*s1==*s2 && *s1!='\0' && *s2!='\0')
	{
		++s1;
		++s2;
		--n;
	}

	return *s1 - *s2;
}

指针 操作 二维数组

int a23;

//二维数组

1.c语言中并不存在,真正的二维数组。

2.二维数组本质 是一维数组的一维数组

3.二维数组 也 符合数组的特点 //连续性,有序性,单一性

//从二维数组的本质出发

int3 a2;

问题:

1.确定需要定义什么类型的指针?

&a0

//a0 --- int3

//&a0 --- int3 *

//c语言中 不支持 int3 *

//正确写法 int(*)3

int(*p)3 = a; //p指向二维数组 a

//p的基类型 int3

*p <=> a0 // 相当于是内部这个一维数组的数组名

(*p)0

*(*p+0) //**p

*(*(p+1)+1) <=> a11

*(*(p+i)+j) <=> aij

注意:

二维数组的操作

从二维数组的本质 进行的

二维数组的本质 一维数组的 一维数组

直接的访问操作 也是 一维一维的展开

cs 复制代码
#include <stdio.h>

int main(void)
{

	int a[2][3] = {1,2,3,4,5,6};

	int (*p)[3] = a;
	int i = 0;
	int j = 0;
	for (i = 0;i < 2; ++i)
	{
		for (j = 0; j < 3; ++j)
		{
			printf("%d ",*(*(p+i) + j));
		}
		putchar('\n');
	}
	
	return 0;
}
相关推荐
是隼人8 分钟前
buuctf-pwn PWN1题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
HugoStudio_SWAN11 分钟前
洛谷 P1321 单词覆盖还原——从蜡板上的密信到数字水印
c++·学习·程序人生·算法
春风解人意15 分钟前
从零开始学习嵌入式P33----网络基础之HTTP
网络·学习·http
励志不掉头发的内向程序员20 分钟前
【LibreCAD 2D架构】从鼠标点击到屏幕像素:LibreCAD绘图架构全链路解析之Action与命令系统
linux·开发语言·c++·qt·学习·系统架构
小道士写程序27 分钟前
自然语言处理NLP - 第8章 词向量与神经网络:从手工特征到学习表示
神经网络·学习·自然语言处理
m4Rk_1 小时前
【论文阅读】Agent 记忆机制(59):Synapse——让相关记忆沿情景—语义图被逐步激活
论文阅读·人工智能·学习·开源·github
William一直在路上2 小时前
MCP 规范版本对比:2025-11-25 vs 2026-07-28
学习·ai·llm
GHL2842710902 小时前
codex操作excel学习
学习·ai·word·excel
励志不掉头发的内向程序员2 小时前
LibreCAD 2D架构】从鼠标点击到屏幕像素:LibreCAD绘图架构全链路解析之鼠标事件与RS_ActionDrawLine
c++·qt·学习·架构·计算机外设
koi77u3 小时前
嵌入式学习————————TCP并发服务器(1)
linux·学习