有关于练习题
普通方法
-
开始想把字符串给dst
竟然用了 char* dst=str;
…给是给了,但是不能对字符串进行操作。因为dst指向常量区。str在形参里是char*,
但是在main函数里是数组形式,因为测试代码的时候他可以改变。 -
然后我想了创建一个字符串数组,用了这样的代码
char dst[100] = "";
strcpy(dst, str);
int n = strlen(str);
for (int i = 0; i < n; i++)
{
*str = *str + 32;
//A B C D E
str++;
//B C D E
//C D E
....
//E
}
脑子又抽了,那你str走到最后,你返回了个啥。返回了个空
- 为什么不直接用这个数组进行解决
char * toLowerCase(char* str){
int n=strlen(str);
for(int i =0;i<n;i++)
{
//必须是A到Z之间才转换小写
if(str[i]<='Z'&&str[i]>='A')
{
str[i]=str[i]+32;
}
}
return str;
}
必须要经常回忆,不然忘光了
位运算方法
大写转小写,小写转大写
每个字母的大小写相差32,就是 2 5 2^5 25用二进制表示是0100000
那么A的ASCII值为65,
2
6
+
1
2^6+1
26+1
二进制为1000001
a的ASII值为97,
2
6
2^6
26+1+
2
5
2^5
25
二进制为:1000001(65) + 0100000(32)=1100001 (97)
A与a,二进制只有第6位不一样,可以用异或运算符。
A的第一位是1,32的第一位是0,A的第6位是0,32的第6位是1,A的最高位是1,32最高位是0。相异为真,A的第一位本来就是1,第6位变成1,最高位本来就是1。A变成a。 (因为32的二进制只有第6位是1)。
所以A转换成a,还可以用A=A^(1<<5)=a
同理a转换成A,可以用a=a^(1<<5)=A,与上面的原理一样
题解:由于是一个字符串,先求出长度,然后循环长度次,对每一个字符进行操作。对于本题只需要大写字符转换小写,写一个if条件判断就好了。大写进行操作,小写就不动
char * toLowerCase(char* str){
int n=strlen(str);
for(int i =0;i<n;i++)
{
if(str[i]<='Z'&&str[i]>='A')
{
str[i]^=32;
}
}
return str;
}
大写转小写,小写转小写
还是以A与a为例。
A:1000001
a: 1100001
32: 0100000
A=A | 32 =a;
a=a | 32 =a;
这样写的好处是,不需要写if语句进行判断,统一处理,小写不变,大写变小写。
char * toLowerCase(char* str){
int n=strlen(str);
for(int i =0;i<n;i++)
{
str[i] |=32;
}
return str;
}
练习题变形
假如有道题,让小写变成大写。还是一样三种方法:
普通方法
if语句变成在小写字母的范围内
for(int i =0;i<n;i++)
{
if(str[i]<='z'&&str[i]>='a')
{
str[i]=str[i]-32;
}
}
位运算方法
大写转小写,小写转大写
A=A^32=a
a=a^32=A
for(int i =0;i<n;i++)
{
if(str[i]<='z'&&str[i]>='a')
{
str[i]^=32;
}
}
小写变大写、大写变大写
还是以A与a为例。
A:01000001
a: 01100001
-33: 10100001
负数必须和他的补码进行运算
-33(取反):11011110(除符号位之外逐位取反)
-33(补码):11011111(+1)
&:全1则1。
A&-33(补码)=01000001
A=A&-33(原码)=01000001=A
晕了,已经是正数了,还在求人家的原码
A&-33(取反)=00111110
A&-33(原码)=00111111
前面算了-33补码,这里直接用
a=a&-33(补码)=01000001=A
所以
A=A&-33=A
a=a&-33=A
for(int i =0;i<n;i++)
{
str[i]&=-33;
}
返回局部变量的地址,回忆并对比引用做返回值
在vs 2013编一个代码时,最后失误返回了一个数组名,这个数组是在函数里开的一个局部变量,相当于我返回了数组第一个变量的地址。所以编译器发出警告。
我们知道实际返回是这样一个过程,临时变量在中间做值拷贝.p出了函数所指向的地址被释放掉了,临时变量的指针还在指,就成了悬空指针。
那么如果p是malloc出来的变量,我返回p,就是返回堆上的地址,是可以的,不过需要你自己用完之后释放内存,指针不用还要置空。
(C++引用做返回值的话p到临时变量不用拷贝)突然想起来C++中引用,
点这个链接,目录里有个引用做返回值可以详细回忆