C语言回顾(四、字符串及其处理函数重写)——iOS开发基础


说明:
在学习UI高级知识之前,将利用最近十来天的时间回顾一下C语言,主要按照《C程序设计(谭浩强版)》来回顾。
整理一些知识点(不是细节,知识个人觉得较重要或易忘的)以及挑一些课后题目或经典习题编写代码练习。
C语言中字符数据应用较广,单独提出来总结!


字符串及其处理函数重写


1、字符串的实质就是数组的存储
(1)C语言规定了一个“字符串结束标志”,以字符’\0’作为结束标志;
(2)因此在程序中往往依靠检测’\0’来判断字符串是否结束,而不是根据数组的长度来决定字符串长度;
(3)printf("Hello, World!\n");实际上在向内存存储时,系统会自动在最后一个字符’\n’的后面加一个’\0’,作为字符串的结束符号。在执行printf函数时,每输出一个字符检查一次下一个字符是否为’\0’,是就停止。

2、字符串初始化
(1)char f[]={'1','2','3'};//不能算字符串,没有’\0’
(2)char f[]={"123"};//”XXX”等价于’X’,’X’,’X’,’\0’;如果定义如下 char b=’\0’;结合数组思想理解,输出b为0;
等价于char f[]="123";
(3)其他形式规定长度之类的此处不列举

3、字符串输入输出
(1)逐个字符输入输出。“%c”
(2)整个字符串一次输入输出。“%s”,printf中得输出项直接写字符数组名,而不是数组元素名(f[0],f[1]之类)
原理如下:(遇到第一个’\0’结束)

for(i=0;f[i]!='\0';i++)
{
    printf("%c",f[i]);
}                           //%s的打印原理
printf("\n");

(3)注意:scanf函数中的输入项如果是字符数组名,不用再加地址符&,因为C语言中数组名代表该数组的起止地址

    char str[5];
    scanf("%s",str);

4、puts函数,与’\0’结束

    char str[] = "China\nWenzhou";
    puts(str);

output:

China
Wenzhou

gets函数:gets(str);输入China,注意是字符串“China”,是6个字符,而不是5个字符,返回字符数组str的起始地址。
注意:上述函数都只能输出或输入一个字符串

5、strcat函数——字符串连接函数(string catenate)
原型:extern char *strcat(char *dest,char *src);
功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)并添加’\0’。
不用strcat函数, 重写my_strcat函数

#include <stdio.h>

char* my_strcat(char* dest,const char* src) {
    if (dest == NULL || src == NULL) {
        return NULL;
    }//安全检查
    while (*dest != '\0') {
        dest++;
    }
    while (*src != '\0') {
        *dest++ = *src++;
    }
    *dest = '\0';
    return dest;
}

int main(int argc, const char * argv[]) {
    char str1[] = "China";
    char str2[] = "Zhejiang";
    my_strcat(str1, str2);
    printf("%s",str1); 
    return 0;
}

output:

ChinaZhejiang

说明:程序自己编写,如有错误,希望大家能够提出指正。

6、strcpy和strncpy函数——字符串复制函数
原型:char *strcpy(char* dest, const char *src);
功能:把从src地址开始且含有’\0’结束符的字符串复制到以dest开始的地址空间
说明:
(1)dest长度必须不应小于src的长度;
(2)strcpy(str1,"China");str2可以是字符串常量,str1必须是数组名;
(3)复制完成,剩余的数组元素不会改变内容。如果str1未初始化或赋值,那么其内容将无法预知;

    char str1[] = "Chinese";
    strcpy(str1, "China");
    printf("%s,%c\n",str1,str1[6]);

output:China,e
(4)strncpy

    char str1[] = "Chinese";
    strncpy(str1, "XXXXX", 2);
    printf("%s\n",str1);

output:XXinese
作用:将str2”XXXXX”中得前2个字符复制到str1中,取代str1中原来的最前面2个字符。
不用strcpy函数, 重写my_strcpy函数

#include <stdio.h>

char* my_strcpy(char* dest,const char* src) {
    char* result = dest;
    if (dest == NULL || src == NULL) {
        return NULL;
    }
    while (*src != '\0') {
        *result++ = *src++;
    }
    *result = *src;
    return result;
}
int main(int argc, const char * argv[]) {
    char str1[] = "China";
    char str2[] = "Zhejiang";
    my_strcpy(str2, str1);
    printf("%s\n",str2);
    return 0;
}

output:China
这里编写完查参考资料的时候,发现在写函数时没有写
char* result = dest;保存dest值说明逻辑思维不严密。这里有点不懂!望大神解答!

7、strcmp函数——字符串比较函数
原型:extern int strcmp(const char *s1,const char *s2);
功能:将两个字符串自左向右逐个字符相比(按ASCII码值大小比较),知道出现不同的字符或遇到’\0’为止
返回值:
当s1小于s2,返回为负数;
当s1等于s2,返回’0’;
当s1大于s2,返回为整数;
说明:正数负数确切数值是依赖不同的C实现的。
(1)一般来说,返回值会是:1 0 -1
(2)有些会把两个字符的ASCII码之差作为比较结果由函数值返回。

不用strcmp函数, 重写my_strcmp函数

#include <stdio.h>

int my_strcmp(const char* s1,const char* s2) {
    if (s1 == NULL || s2 == NULL) {
        return 10000;
    }
    while (*s1 == *s2) {
        if (*s1 == '\0') {
            return 0;
        }
        s1++;
        s2++;
    }
    return *s1-*s2;
}

int main(int argc, const char * argv[]) {
    char s1[] = "China";
    char s2[] = "China";
    char s3[] = "America";
    char s4[] = "Wenzhou";
    printf("%s %s %d\n",s1,s2,my_strcmp(s1, s2));
    printf("%s %s %d\n",s1,s3,my_strcmp(s1, s3));
    printf("%s %s %d\n",s1,s4,my_strcmp(s1, s4));
    return 0;
}

output:

China China 0
China America 2
China Wenzhou -20

这里有个小问题,安全检查返回值是int类型能否有更好地处理方法,除了返回一个异常的数字外?

8、strlen函数——测字符串长度的函数
原型:extern unsigned int strlen(char *s);
——————
size_t strlen(const char *);
功能:测试字符串长度,不包括’\0’在内
说明: 注意strlen与sizeof的区别!!!

    char s[10] = "China";
    printf("%lu\n",strlen(s));

output:5 结果是5,不是10,也不是6。

不用strlen函数, 重写my_strlen函数

#include <stdio.h>

int my_strlen(const char* str) {
    unsigned int size = 0;
    if (str == NULL) {
        return -1;
    }
    while (*str != '\0') {
        size++;
        str++;
    }
    return size;
}

int main(int argc, const char * argv[]) {    
    char s[] = "China";
    printf("%d\n",my_strlen(s));
    return 0;
}

output:5

9、strlwr函数——转换为小写的函数(string lowercase:字符串小写字母)
原型:extern char *strlwr(char *s);
功能:将字符串中大写字母换成小写字母,返回指向s的指针
兼容性说明:strlwr和strupr不是标准C库函数,只能在VC中使用。linux gcc环境下需要自行定义这个函数。(Xcode会报错)
用的较少,此处就不重写的,原理与上类似。

10、strupr函数——转换为答谢的函数(string uppercase:字符串大写)
原型:extern char *strupr(char *s);
功能:将字符串中小写字母换成大写字母,返回指向s的指针
兼容性说明:strlwr和strupr不是标准C库函数,只能在VC中使用。linux gcc环境下需要自行定义这个函数。(Xcode会报错)
用的较少,此处就不重写的,原理与上类似。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值