学习指针第三日

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 a[2][3];

//二维数组

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

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

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

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

int[3] a[2];

问题:

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

&a[0]

//a[0] --- int[3]

//&a[0] --- int[3] *

//c语言中 不支持 int[3] *

//正确写法 int(*)[3]

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

//p的基类型 int[3]

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

(*p)[0]

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

*(*(p+1)+1) <=> a[1][1]

*(*(p+i)+j) <=> a[i][j]

注意:

二维数组的操作

从二维数组的本质 进行的

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

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

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;
}
相关推荐
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意4 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码4 天前
嵌入式学习路线
学习
毛小茛4 天前
计算机系统概论——校验码
学习
babe小鑫4 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习