指针
- 指针就是变量,用来存放地址的变量
int *p
:指针变量p里面存放整型变量地址
**(*p):解引用操作,是p所指向的内容 ** - 指针的初始化是用&操作符完成的,它用于产生操作数的内存地址
- 指针的大小在32位平台上是4 个字节,在64位平台是 8个字节
- 指针是有类型的类型是:type+ 的方式
ex: char 类型的指针是为了存放 char 类型变量的地址
int* 类型的指针是为了存放 int 类型变量的地址 - 指针的类型决定了指针向前或者向后走一步有多大(距离)
- 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)
ex : char* 的指针解引用就只能访问一个字节,
int* 的指针解引用能访问四个字节
###二级指针
- 指针变量也是变量,是变量就有地址,那么指针变量的地址则存放在 二级指针
2 .*( * ppa)通过对 ppa中的地址进行解引用,这样就找到的是 pa,(* ppa)其实访问的就是 pa ; 然后对 pa 进行解引用操作 (pa),那找到的就是 a。
###指针表达式解析
看下列代码,能否做左值?能否做右值?
左值表示 空间;右值表示 内容
&ch ;
&ch是地址变量,不能做左值,但是可以做右值
cp ;
cp是变量,可以做左值,可以做右值
&cp ;
&cp是地址变量,不能做左值,但是可以做右值
*cp+1;
*cp+1 表达式的结果是常量,不能做左值,但是可以做右值
*(cp+1)||( *++cp );
二者表示ch 之后的一块空间,可以做左值,也可以做右值
++cp;
++cp 前置++ 不能作为左值,可以是右值
cp++;
cp++ 后置++ 不能作为左值,可以是右值
C语言规定:前置++不能作为左值;但C++语言规定可以
###指针运算
- 指针±整数
- 指针-指针
结果是中间元素的个数,且两个指针指向同一个内存块 - 指针的关系运算
标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较;但不允许与前面的那个内存位置的指针进行比较
###模拟实现strcpy函数(指针)
- 字符串拷贝函数;第一个参数是目标,第二个参数是源
char *my_strcpy(char *dest,const char *str)
{
char *ret=dest;
assert(dest);
assert(str);
while(*str!='\0')
{
*dest=*str;
str++;
dest++;
}
*dest=='\0';
return ret;
}
###模拟实现strcat函数
- 字符串拼接函数,不能自己追加在自己后面,因为自己的‘\0’被覆盖,字符串没有了结束标志
char *my_strcat(char *dest,const char *str)
{
char *ret=dest;
assert(dest);
assert(str);
while(*dest)
{
dest++;
}
while((*dest++ = *str++))//这一句不能分开写在循环里面的原因是:str字符串的‘\0’拷贝不过去
{
;
}
return ret;
}
###模拟实现strstr函数
- 该函数判断substr是否为str的子串
char *my_strstr(const char *str,const char *substr)
{
assert(str);
assert(substr);
while(*str)
{
const char *s1=str;//指针指向起始位置,后面会向后走
const char *s2=substr;
while(*s1 && *s2 && *s1==*s2)
{
s1++;
s2++;
}
if(*s2=='\0')
return str;
str++;
}
return NULL;
}
###模拟实现strchr函数
- 找出某字符在字符串里的位置
char *my_strchr(char *str,char ch)
{
assert(str);
while(*str!=0)
{
if(*str==ch)
return str;
str++;
}
return NULL;
}
###模拟实现strcmp函数
- 字符串比较函数
- 在VS环境下,两个相等,返回0;第一个比第二个大,返回1;第二个比第一个大,返回-1
int my_strcmp(const char *str1,const char *str2)
{
while(*str1==*str2)
{
if(*str1=='\0')
return 0;
str1++;
str2++;
}
if(*str1>*str2)
return 1;
else
return -1;
}
###模拟实现memcpy函数
- 内存拷贝函数
void * my_memcpy(void *dest,void *str,size_t count)//void* 无类型指针,不能参与运算
{
void *ret=dest;
assert(dest);
assert(str);
while(count--)
{
*(char*)dest=*(char*)str;
dest=(char*)dest+1;
str=(char*)str+1;
}
return ret;
}
###模拟实现memmove函数
- 实现重叠拷贝函数
void * my_memmove(void *dest, const void* src,
size_t count)//size_t 无符号整型
{
void* ret = dest;
assert(dest != NULL);
assert(src != NULL);
if(dest<src)
{
while(count--)//从前往后拷贝
{
*(char *)dest = *(char *)src;
dest = (char *)dest+1;
src = (char *)src+1;
}
}
else
{
while(count--)//从后往前拷贝
{
*((char *)dest+count)= *((char *)src+count);
}
}
return ret;
}