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. 拷贝
'\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;
}