指针操作一维字符型数组
char s[ ] = "hello";
char *P = s; //推导过程与一维整型数组一样
在学习一维字符型数组时,可以回忆之前所学的puts函数来加深理解
int puts(const char*s);
const //只读
const放在不同位置限定的范围不同
int a = 10;
const int *p = &a; //限定的是基类型Int,表示不能通过*p的方式修改基类型数据
int const *p = &a; //限定的是基类型Int,表示不能通过*p的方式修改基类型数据
int *const p = &a; //限定的是指针变量p,将p限定为只读,表示p不能修改
const int * const p = &a//基类型变量和指针都被限定为只读,p = &a;*p = a;都不能改
应用:
1.如果不行通过*p方式改变基类型对应的数据
const int *p = &a;
int const *p = &a;
2.如果指针变量p定义好后,不想在指向别的变量
int *const p = &a;
const限定原则:就近原则 //const离谁近就限定谁
在了解了const的作用后,就可以知道puts函数的形参为什么要用const char *s了
1.目的:防止函数中的误操作
2.好处:提前发现问题,将运行时问题提前到编译
指针 + 字符串
字符串 //在c语言中是按照字符数组的形式存储
//字符串常量 --- 存储在字符串常量区
处理字符串:
char s[ ] = "hello"; //表示在栈上开辟一片空间,用字符串常量中的"hello"进行初始化
const char *p = "hello" //表示p指向了字符串常量区中的"hello",因为是指向字符串常量区,所以只能做读取操作,不能修改
总结:
1.指针操作一维字符型数组 //字符串
2.知识点
(1)指针变量的类型是怎么确定的?
(2)一维字符型数组和字符串的关系
(3)处理字符串数据的方式
char s[ ] = "hello";
const char *p = "hello";
(4)const 关键字
const关键字的使用方法
const关键字的形参
3.实现字符串相关函数
gets
char *Gets(char *s)
{
char *p=s;
do
{
*s = getchar();
}while(*s++ != '\n');
*--s = '\0';
return p;
}
puts
void Puts(const char *p)
{
while(*p != '\0')
{
printf("%c",*p);
p++;
}
putchar('\n');
}
strlen
size_t Strlen(const char *s)
{
//int len=0;
const char *p = s;
while(*s != '\0')
{
s++;
//len++;
}
return s-p;
}
strcpy/strncpy
char *Strcpy(char *dest,const char *src)
{
char *ret=dest;
while(*src != '\0')
{
*dest++ = *src++;
}
*dest = '\0';
return ret;
}
char *Strncpy(char *dest,const char *src,size_t n)
{
char *ret=dest;
while(dest-ret < n)
{
if(*src == '\0')
{
*dest='\0';
}
else
{
*dest = *src;
}
dest++;
src++;
}
return ret;
}
strcat/strncat
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,size_t n)
{
char *ret = dest;
const char *p = src;
while(*dest != '\0')
{
dest++;
}
while(src - p < n)
{
if(*src == '\0')
break;
else
{
*dest = *src;
}
dest++;
src++;
}
*dest = '\0';
return dest;
}
strcmp/strncmp
int Strcmp(const char *s1,const char *s2)
{
int ret;
while(*s1 == *s2 && *s1 != '\0' && *s2 != '\0')
{
s1++;
s2++;
}
return *s1 - *s2;
}
int Strncmp(const char *s1,const char *s2,size_t n)
{
int ret;
while(*s1 == *s2 && *s1 != '\0' && *s2 != '\0' && n-1)
{
s1++;
s2++;
n--;
}
return *s1 - *s2;
}
void *memecpy(void *dest,const void src,size_t n)
void * //空类型的指针 -- 万能指针
注意:
1.如果用空类型的指针进行间接运算,必须转换成有明确类型的指针
指针操作二维数组
回顾二维数组
1.C语言中并不存在真正的二维数组
2.二维数组本质是一维数组的一维数组
3.二维数组也符合数组的特点 //连续性,有序性,单一性
从二维数组的本质出发
int (*p)[3]; //p指向二维数组
此时*p <=> a[0] //相当于是内部这个一维数组的数组名
对于具体的元素可用**p <=>*(*p+0)这只对应一维数组a[0]中的元素
可以继续引申得*((*p+i)+j)<=>a[i][j]