指针操作 一维 字符数组
- 字符型数组 --- 存放字符串的
char s[] = "hello";
['h' ] <---0x1000
['e' ]
['l' ]
['l' ]
['o' ]
['\0']
//谁能这块空间的地址 --- 数组名
s --->怎么能保存s所代表的地址值
//s数组名 --- 数组首元素的地址 &s[0]
--->地址的类型
char *
char *p = s; //指针变量p 指向了 s (数组)
int puts(const char *s);
注意:
char s[] = "hello"; //s的空间开在 栈上
char *s1 = "hello"; //s1的空间开在栈上,但是s1指向的"字符串常量"
//存放"字符串常量区"
*s1 = *s1 - 32; //不能做 ? 原因是 s1 指向的数据是在 字符串常量区
//常量区的数据不能修改
const int a = 10; //a成了只读变量
const char * s1 = "hello"; //表示 将 *s1 限定为只读
//如果,不希望修改 *s1 的数据
//一般 建议加上const
char * const s1 = "hello"; //const 离谁近,就是限定谁的
char const *s1 = "hello"; //此时 还是 *s1 不能被修改
int *p; //int 代表基类型
//p 本身
char const * const s1 = "hello"; // *s1 和 s1 本身都不能被修改
总结:
1.const 离谁近,就限定谁
2.const 修饰的变量,为只读变量 //变量还是变量 只是成了只读的
实现:
int Puts(char *s)
{
*s = 'a'; //编译时,不报错
}
int Puts(const char *s)
{
*s = 'a'; //编译时,就会报错
}
const char *s // *s 这种方式修改不了数据
形参设计:
什么时候需要加const
1.如果函数内部本身不需要通过*s 修改外面的数据
此时,建议 统统加上const
好处:
1.可以将 错误提前 到 编译时 发现
2.提高了参数的适用性
可以接收数组名
也可以接收 字符串常量 //const char *
练习:
strlen
int Strlen(const char *s)
{
}
size_t Strlen(const char *s)
{
}
练习:
Strcpy(char *dest,const char *src)
char *Strcpy(char *dest, const char *src)
{
char *ret = dest;
...拷贝过程
return ret;
}
返回值:
成功 表示的是dest的首地址
返回值设计成char * 是为了实现 字符串链式操作
char *strncpy(char *dest, const char *src, size_t n);
功能
将src中的前n个字节拷贝到 dest中
注意:
src 长度 > n 此时将前n个字节拷过去,此时dest也不会拷过去'\0'
src 长度 < n 此时将src拷贝完成后,继续拷贝(添加的是'\0')直到完成了n次拷贝
char * Strncpy(char *dest,const char *src, size_t n)
{
//这个函数,拷贝过程,n来控制
}
char src[] = "hello";
strncpy(dest,src,10); //
练习:
strcat
char *strcat(char *dest, const char *src);
功能:
拼接字符串
实现: //返回值 表示的是dest 存放字符串的空间的首地址
char *Strcat(char *dest, const char *src)
{
char *ret =dest;
//1.先定位到 dest 的 '\0'的位置
//2.从dest的 '\0'位置开始,拷贝字符串
//3.最终dest中 需要有 '\0'结束标志
return ret;
}
char *strncat(char *dest, const char *src, size_t n)
功能:
将 src中的前 n 个字符拷贝过去
注意:
始终保证 dest中是一个字符串 ('\0')结束标志的
//使用时,需要确保dest空间足够
char * Strncat (char *dest, const char *src, size_t n)
{
char *ret =dest;
//1.先定位到 dest 的 '\0'的位置
//2.从dest的 '\0'位置开始,拷贝字符串 //受到n的控制
//3.最终dest中 需要有 '\0'结束标志
return ret;
}
Strcmp(const char *s1,const char *s2)
int Strcmp(const char *s1, const char *s2)
{
功能:
从左到右,逐个字符比较
遇到不同的字符时结束 或者 遇到 '\0'
返回 最终不同的字符的差值
}
int strncmp(const char *s1, const char *s2, size_t n);
strncmp("hello","helloa",3); //
int Strncmp(const char *s1, const char *s2, size_t n)
{
功能:
从左到右,逐个字符比较
遇到不同的字符时结束 或者 遇到 '\0' n个比完也停
返回 最终不同的字符的差值
}
总结:
指针操作一维数组
思路,
通过指针变量 获得数组所在空间的地址
int a[10];
int *p = a;
*(p+i) <=> a[i]
函数实现的
printArray(int *a,int len)
{
}
Puts(const char *s)
{
}
指针 操作 二维数组
int a[3][4] = {1,2,3,4,5,6,7,8,9};
a 还是首元素的地址
a[0]
a[0][0]
int[4] a[3]; //a数组名 -- &a[0]
a<=>&a[0] //值的角度
a[0] //数据类型 int[4]
&a[0] //int[4] * 指针类型
//标准C语法: int (*)[4]
定义变量:
int (*p)[4]; //数组指针
//基类型 int[4]这种类型 ---数组类型
*p //等价与 a[0]
//相当于是 int[4] 这个一维数组的数组名
*(*(p+0)+0) <=> a[0][0]
*(*(p+i)+j) <=> a[i][j]