*s与s[]字符串赋值时的区别,统计字符串中的大小写以及小写改大写
实现功能:数组小写字母统计以及小写字母改大写
1、正确运行的程序源码
#include <stdio.h>
#include <ctype.h>
int small(char * const a,int m);
int main(int argc, char *argv[])
{
char s[]="88 heLLo world!,china";
int n = 0;
int m = 0;
puts(s);
m = sizeof(s)/sizeof(char);
n = small(s,m);
printf("%d \n",n);
puts(s);
return 0;
}
int small(char * const a,int m)
{
int n = 0;
for(int i = 0;i < m ;i++)
{
if(islower(*(a+i)))
{
n++;
*(a+i) = toupper(*(a+i));
}
}
return n;
}
运行结果
88 heLLo world!,china
13
88 HELLO WORLD!,CHINA
2、错误的程序源码
将字符串数组赋值s[] = 改为*s = 后编译通过,运行报段错误
char *s="88 heLLo world!,china";
运行结果
88 heLLo world!,china
段错误 (核心已转储)
3、错误原因
*s中的s存储的是"88 heLLo world!,china"的地址,属于房产证,是变量,如果对s进行加减操作,那么是指针s所在的位置的加减操作,即换了一本房产证,而不是字符串地址的加减操作,相当于访问了不改访问的地址,导致运行报段错误;
s[]中的s是"88 heLLo world!,china"的首地址,属于房子,是常量,不能对s进行加减操作,但是可以以这个为参考对后续的元素进行访问,如*(s+i)。
结合下列图,可以更好理解这个差异。
4 另外一种解决办法
在使用前申请一段内存,可以解决这个问题,使用malloc申请了一段字符串长度的内存空间,使用完后将其释放。新的主函数如下:
int main(int argc, char *argv[])
{
char *s;
int n = 0;
int m = 0;
m = sizeof("99 88 heLLo world!,china");
s = malloc(m);//申请一段内存地址
strcpy(s,"88 heLLo world!,china");
puts(s);
n = small(s,m);
printf("%d \n",n);
puts(s);
free(s);//释放内存地址
return 0;
}