指针运算:
&
*
+N
-N
p++ //往后跳了一个元素
p-- //往前一个元素
p-q //相同类型的指针 减出的来的结果为 ,地址之间相差的元素个数
关系运算:
p > q
p < q
> >= < <= !=
迭代:
迭代其实就是一种特殊的循环,迭代根据上一次循环得到的运算结果来进行下一次的迭代,与一般循环固定的结束条件不同,迭代转为设置循环的开始与结束条件,这样可以让我们在使用中更加灵活。逆序的迭代写法:(一般写法为计算长度后规定循环次数然后逆序)
void reverse(char *begin,char *end)
{
while(begin<end)
{
char tmp=*begin;
*begin=*end;
*end=tmp;
begin++;
end--;
}
}
指针操作 一维 字符数组
1. 字符型数组 --- 存放字符串的
char s[] = "hello";
['h' ] <---0x1000
['e' ]
['l' ]
['l' ]
['o' ]
['\0']
//谁能这块空间的地址 --- 数组名
s --->怎么能保存s所代表的地址值
//s数组名 --- 数组首元素的地址 &s[0]
--->地址的类型
char *
char *p = s; //指针变量p 指向了 s (数组)
注意:
char s[] = "hello"; //s的空间开在 栈上 (堆,栈,字符串常量区,全局区(静态区),代码区)
char *s1 = "hello"; //s1的空间开在栈上,但是s1指向的"字符串常量"
//存放"字符串常量区"
*s1 = *s1 - 32; //不能做 ? 原因是 s1 指向的数据是在 字符串常量区
//常量区的数据不能修改
const应用:
const int a = 10; //a成了只读变量
const char * s1 = "hello"; //表示 将 *s1 限定为只读
//如果,不希望修改 *s1 的数据
//一般 建议加上const
char const *s1 = "hello"; //此时 还是 *s1 不能被修改
也就是说,const char * s1与 char const *s1的效果是一样的
char * const s1 = "hello"; //const 离谁近,就是限定谁的
int *p; //int 代表基类型
//p 本身
char const * const s1 = "hello"; // *s1 和 s1 本身都不能被修改
总结:
1.const 离谁近,就限定谁 (离类型近,值不能改,离变量名(指针)近,地址不能修改)
2.const 修饰的变量,为只读变量 //变量还是变量 只是成了只读的
3.这里说明,char *a=“hello”; //此处hello存于字符串常量区
char ch[ ]=“hello”; const char *a=&ch; //此处a的值存于栈中,但是不可读
且char *a=“hello”,char *b=“hello”,不论几个,字符串常量区只有一个hello,a,b均指向它
为什么strcpy要返回char*?
为了使用链式表达式
形参设计:
形参设计:
什么时候需要加const
1.如果函数内部本身不需要通过*s 修改外面的数据
此时,建议 统统加上const
好处:
1.可以将 错误提前 到 编译时 发现
2.提高了参数的适用性
可以接收数组名
也可以接收 字符串常量 //const char *
实现:
int Puts(char *s)
{
*s = 'a'; //编译时,不报错
}
int Puts(const char *s)
{
*s = 'a'; //编译时,就会报错
}
const char *s // *s 这种方式修改不了数据
快速排序:
假定key值为每轮次第一个元素
从end右找小的,begin从左找大的,交换到移动标记begin和end重合,或者找到符合大小的数
由于begin和end并不是一起动的,所以它们必相遇,也就是begin和end同一位置(一起动才不一定相遇)
交换begin和key的位置,此时key的左边全是比k小的,右边全是比k大的
分成两个数组继续递归排序,直到只剩一个数(或者还剩两个数排完)-->(begin<=end)
void quickSort(int *begin,int *end)
{
int *p=begin;
int *q=end;
int *k=NULL;
if(begin>=end) //此时应该是只有一个元素,或只有两个元素排序完的情况
return ;
k=begin;
while(begin<end)
{
while(begin<end && *end>=*k) //此处begin<end必须放在前面,
end--; //不然会导致越界问题(段错误)
while(begin<end && *begin<=*k)//此处=不能省,因为其目标是找到<的数
begin++;
swap(begin,end);
}
swap(begin,k); //key
quickSort(begin+1,q); //此时begin和end是相同的,这么写是为了可读性好
quickSort(p,end-1);
}
单词倒置:"how are you" -> "you are how"
基本思路:整个字符串逆序-->每个单词逆序
(整个字符串逆序使单词的次序改编版,单词逆序两次变回原样)
以空格或'\0'为判断标志,自增end,直到遇到标志时对end前面单词进行逆序,完成后将begin移动至标志后一位,直到遇到'\0'后begin结束移动,并返回逆序后的字符串
void reverse(char *begin,char *end)
{
while(begin<end)
{
char tmp=*begin;
*begin=*end;
*end=tmp;
begin++;
end--;
}
}
char *reverse_string(char *p,int len)
{
char *end,*begin;
begin=p;
reverse(p,p+len-1);
while(*begin)
{
end=begin;
while(*end != '\0' && *end != ' ')
{
end++;
}
reverse(begin,end-1);
if(*begin == ' ') //倒置结束时,begin在最后一个单词,将begin移至下次开始位置
{
begin=end+1;
}
else //到达'\0'后循环结束
{
begin=end;
}
}
return p;
}