#include
void mystrupr(char *str)
{
while(*str)
{
if(*str >= 'a' && *str <= 'z')
*str -= 'a' - 'A';
str++;
}
}
int main()
{
char str[] = "Hello World";
mystrupr(str);
printf("%s",str);
return 0;
}
核心代码:
while(*str)
{
if(*str >= 'a' && *str <= 'z')
*str -= 'a' - 'A';
str++;
}
小写字母的ASCII要大32
即'a' - 'A' == 32,所以换成32也可
#include
int mystrlen(char *str)
{
int len=0;
while(*str++)
{
len++;
}
return len;
}
int main()
{
char str[] = "Hello World";
printf("%d",mystrlen(str));
return 0;
}
注意:函数命名时,返回什么类型就用什么类型
因为字符串不能直接用”=“进行赋值,要用mystrcpy,所以我觉得也可以叫赋值字符串
#include
char *mystrcpy(char *str1,const char *str2)
{
while(*str2 != '\0')
{
*str1 = *str2;
str2++;
str1++;
}
*str1 = '\0';
return str1;
}
int main()
{
char s1[30],s2[30],s3[30];
gets(s1);
mystrcpy(s3,mystrcpy(s2,s1));
printf("%s\n",s1);
printf("%s\n",s2);
printf("%s",s3);
return 0;
}
函数部分可以有所改进:
1)while条件中,由(*str2 != '\0')改为(*str1++ = *str2++),指针的移动和复制都在一行中运行,更加简洁,同时后面的*str1 = '\0';也不用了
2)return str1;可能存在问题,因为在前面的操作中,指针是指向最后一个字符的,返回后可能对后面有影响,所以要再定义一个指针进行储存
注意:while可以是空主体,但不要忘了;结尾
改进后:
#include
char *mystrcpy(char *str1,const char *str2)
{
char *start = str2;
while(*str1++ = *str2++);
return start;
}
int main()
{
char s1[30],s2[30],s3[30];
gets(s1);
mystrcpy(s3,mystrcpy(s2,s1));
printf("%s\n",s1);
printf("%s\n",s2);
printf("%s",s3);
return 0;
}
改进过后我又有了新发现:
前置
int i = 5;
int j = ++i; // i 先增加到 6,然后 j 被赋值为 6
printf("i = %d, j = %d\n", i, j); // 输出: i = 6, j = 6
在int j = ++i;中,有两个步骤,++和=,因为++在前,所以先把i加1,再把增加后的i赋给j
后置
int i = 5;
int j = i++; // j 被赋值为 5,然后 i 增加到 6
printf("i = %d, j = %d\n", i, j); // 输出: i = 6, j = 5
同理,只是++在后,先把i赋给j,再把i加1
就是一个运行循序的问题
首先,括号里面不仅仅是一个用来判断的条件,准确来说是一个可以有操作的语句,也就是表达式
正如代码中的赋值,++自增操作
其次,如果循环主体只有一句,可以不用{},(这与if、for一样)
也可以没有主体,但一定要以;结尾,
记得之前上课时,还因为如下情况,被批评  ̄へ ̄
while(条件);//这里
{
主体
}
特殊情况是要加那个分号的:
while(*str1++ = *str2++);
*str1++ = *str2++这个表达式的值就是*str1,循环就是以这个指针指向'\0'结束
我不禁产生'\0'和0,抑或是其它含0的,是否都有false的含义
我发现:只有'\0'没有真值,即false含义,但指向它的指针,即空指针是有false含义
从deepseek中得到以下结果:
数据类型 | 值为 0 或包含 0 |
布尔上下文中的意义 |
---|---|---|
整数 | 0 |
false |
整数 | 非零(如 10 、-1 ) |
true |
字符串 | '\0' (字符串结束符) |
不影响字符串指针的真值 |
指针 | NULL 或 0 |
false |
指针 | 非空指针 | true |
浮点数 | 0.0 |
false |
浮点数 | 非零(如 0.1 、-0.5 ) |
true |
while(*str1++ = *str2++);
总结一下这个表达式:把str2的字符逐一赋值给str1,每一次先赋值,然后同时自增移动,根据赋值表达式的值为左值,所以表达式的值为指针*str1,循环以*str1指向'\0'结束,因此实现了字符串的拷贝,并且'\0'也拷贝上了。
这个cat不是猫,在计算机领域,有显示和连接之意
#include
char *mystrcat(char *str1,char *str2)
{
char *end=str1;
while(*str1)
{
str1++;
}
while(*str1++ = *str2++);
return end;
}
int main(void)
{
char s1[100] = "Winter ", s2[60] = "is ", s3[30] = "comming.";
mystrcat(s1, mystrcat(s2, s3));
printf("%s", s1);
return 0;
}
1)这个地方我有所悟:定义一个指针end指向指针 str1,本质上是保存了str1的第一个字符的地址,地址是不变的(前提是在程序的每一次运行中,因为操作系统会动态分配内存),尽管后面str1的内容发生了改变,但它第一个字符的地址不会改变,最后返回的指针end,仍指向同一个字符串的第一个字符
换句话说,字符串后面的字符改变后,改变之前指向第一个字符的指针仍指的是同一字符串,并不会产生新的字符串
在思考的过程中,我又再想,指针str1是'W'的地址,指针end是str1的地址,把'W'比作一个地点,而str1就这个地点的地图,而end又是标记str1这个地图的位置的地图,看似形象,但指针的移动又该怎么解释呢?
最后眼前一亮:指针的全称是指针变量,变量!!
变量是在内存中的一片空间,空间里是用来表示01的开关,以二进制来表示这个变量的值
现在在内存中开辟一片空间,这个空间命名为str1,在这个空间中某一段通过开关表示的二进制数(根据ASCII码)表示出字母,储存其中
而地址并不是由空间里的开关(存储单元)表示,开关(储存单元)用于存储数据,也就是数字,字符等,
char *end=str1;
总结一下这段代码:作用时让指针重新指回第一个字节
向内存申请一片空间,命名为end
(空间由起始地址和大小【多少个字节】决定,命名是为了方便访问)
空间内的数据为另一片空间str1的地址,
而str1是s2的虚参,一个指针一个字符型数组,本质上是一个东西(数组是只能指向第一位,不能移动的指针),
所以str1有双重身份,
作数组时,str1空间内的数据是'Winter'的ASCLL码,作指针时,str1空间内的数据是'Winter'的'W'的地址
补:与指针相比,数组除了不能移动,也不能被赋值,因为数组名还叫做常量指针(int*const)
想要赋值,可以用循环逐一赋值,抑或用指针来遍历
2)三种情况:
最终指向'\0'
while(*str1)
{
str1++;
}
越界
while(*str1++);
指向'\0',但跳过第一个字符
while(*++str1);
#include
int mystrcmp(const char *s1, const char *s2)
{
while(*s1 != '\0' && *s2 != '\0')
{
if(*s1 == *s2)
{
s1++;
s2++;
}
else if(*s1 > *s2)
return 1;
else
return -1;
}
return 0;
}
int main()
{
char s1[30], s2[30];
scanf("%s", s1);
scanf("%s", s2);
if (mystrcmp(s1, s2) > 0)
{
printf("%s > %s\n", s1, s2);
}
if (mystrcmp(s1, s2) == 0)
{
printf("%s == %s\n", s1, s2);
}
if (mystrcmp(s1, s2) < 0)
{
printf("%s < %s\n", s1, s2);
}
return 0;
}
优化:
#include
int mystrcmp(const char *s1, const char *s2)
{
while(*s1 && *s2 && *s1 == *s2)
{
s1++;
s2++;
}
return *s1 - *s2; //更简洁
}
int main()
{
char s1[30], s2[30];
scanf("%s", s1);
scanf("%s", s2);
if (mystrcmp(s1, s2) > 0)
{
printf("%s > %s\n", s1, s2);
}
if (mystrcmp(s1, s2) == 0)
{
printf("%s == %s\n", s1, s2);
}
if (mystrcmp(s1, s2) < 0)
{
printf("%s < %s\n", s1, s2);
}
return 0;
}
#include
int myatoi(const char *s)
{
int num = 0;
while(*s != '\0')
{
if(*s >= '0' && *s <= '9')
{
num = *s - '0' + num * 10;
}
s++;
}
return num;
}
int main(void)
{
char s1[30] = "ab6@0gap49$";
char s2[30] = "5rt1";
int x = myatoi(s1);
int y = myatoi(s2);
int z = x + y;
printf("%d + %d = %d\n", x, y, z);
return 0;
}
字符变整数,减一个'0'即可
拨开云雾终见月,愿你写代码,如诗般轻盈~~
"今天是我的生日,愿你们也能在代码的世界里找到属于自己的快乐!"