C语言复习 -- 字符串

概念&定义

字符串 -- 就是字符数组

两种定义方式:


char str[]="hello";    //字符串变量,能修改
char *str1="hello";   //字符串常量,不允许被修改

printf -- %s -- 控制字符串输入

//野指针 -- 没有明确的内存指向


#include<stdio.h>

int main()
{
    
    char  str[]={'h','e','l','l','o'};
char str2[]="hello";
    char *str3="hello";
    // for(int i=0;i<5;++i)
    // {
        // printf("%c",*(str3+i));
        
    // }

    str2[3]='m';
        printf("%s\n",str2);
        // str3[0]='m'; // 不可以
            printf("%s\n",str3);
    return 0;
}


================================================

字符串和字符数组的区别:  -- ‘/0’

char  str[]={'h','e','l','l','o'};
char str2[]="hello"; //在调用的"" 修饰字符串的时候,会在最后一个字符后面加入字符串结束标准-- '/0'
str2[] ={'h','e','l','l','o','/0'};

验证程序:


#include<stdio.h>

int main()
{
    
char  str[]={'h','e','l','l','o'};
char str2[]="hello";
char *str3="hello";
int len1=sizeof(str)/sizeof(str[0]);
int len2=sizeof(str2)/sizeof(str2[0]);
int len3=sizeof(str3)/sizeof(str3[0]);

printf("len1: %d\n",len1); // 5
printf("len2: %d\n",len2); // 6
printf("len3: %d\n",len3); // 8  -- 他是一个指针


    return 0;
}


================================================

sizeof  和 strlen ---的区别

计算字符串大小一般使用 strlen -- 只计算有效字符的长度 ,不算'/0'


sizeof  -- 计算整个数组的大小
strlen  -- 计算有效字符的大小


#include<stdio.h>
#include<string.h>

int main()
{
    
char  str[]={'h','e','l','l','o'};
char str2[100]="hello";

printf("sizeof() -- %d\n",sizeof(str2)); // 100 后面多个,未初始化的空间用'/0'填充
printf("strlen() --%d\n ",strlen(str2));  // 5 个有效字符


char *str3="hello";

printf("sizeof(str3):%d\n",sizeof(str3)); //8  -- 指针
printf("sizeof(char*):%d\n",sizeof(char*));//8
printf("sizeof(int*):%d\n",sizeof(int*));//8

printf("strlen(str3):%d\n",strlen(str3)); //5

    return 0;
}

================================================

动态内存管理

malloc -- 动态开辟字符串:


原型:void* malloc(size); -- 分配所需的内存空间,并且返回指向这段空间的指针


注: malloc  在上面开辟空间,要到程序结束的时候才释放,需要手动free 释放
而 局部变量 是在栈 上面开辟的空间,出了函数就释放了

realloc  --  扩容


原型: void *realloc(void *ptr,size);
尝试重新调整 之前使用malloc 或者 calloc 所分配的内存块大小

free


原型: void free(void *ptr); -- 释放之前malloc,clloc,realloc 所分配的内存空间


-- 防止内存泄漏

memset();  -- 内存初始化


原型:void *memset(void *str,int c,size_t n);  ,作用是将某一块内存中的全部设置为指定的值

 

  • str指向要填充的内存块。
  • c是要被设置的值。
  • n是要被设置该值的字符数。
  • 返回类型是一个指向存储区s的指针。

   char *str;
    str=(char*)malloc(5);
    memset(str,'\0',5);
    


悬挂指针 -- 野指针的一种


当指针指向的内存空间已经被释放,但是该指针没有任何的改变,以至于仍然指向已经被回收的内存地址,这种情况下该指针就被称为悬挂指针。


int *p;
p=(int*)malloc(5);
free(p); //这个时候是悬挂指针
p=NULL; // 赋值后不再悬挂
p=(char*)malloc(20);

野指针
        野指针是指尚未初始化的指针,它指向的地址是未知的、不确定的、随机的。

产生的原因:
        释放内存后指针没有及时置空,依然指向该内存,有可能会出现非法访问的错误。

避免方法:
初始化置NULL
申请内存后判空
指针释放后NULL
使用智能指针

================================================

常见字符串操作API

输出字符串:put printf


char *str; 

puts(str);
printf("%s\n",str);


获取字符串:gets scanf


scanf("%s",str):
原型: char  *strcpy(char *dest,const char *src);


gets()
原型: char *gets(char* str);
: 因为改函数可以无限读取,容易发送溢出,溢出的字符覆盖到堆栈中的内容中,破坏其他变量的值

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char  *str="wasaiwnh";
    puts(str);
    printf("%s\n",str);
    char *str2;
    puts("请输入一个字符串:");
    //scanf("%s",str2);
    gets(str2);
    puts(str2);
    return 0;
}

strcpy();  -- 字符串拷贝

strcpy()-是将一个字符串复制到另一块空间地址中 的函数,‘\0’是停止拷贝的终止条件

原型: char* strcpy(char* destination,const char* source);

   1. 函数的参数:

char* destination---------目标字符串的首地址
const char* source------源地址:被复制的字符串的首地址,用const修饰,避免修改掉被拷贝的字符串
   2.函数的返回值类型:char*:返回的是目标字符串的首地址 

strncpy();  -- 字符串拷贝
char* strncpy(char* str,const char *scr,int count);  -- 指定复制长度count 的 拷贝

test  

重写上面两个拷贝
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

char *myStrcpy(char *des,char *src )
{
if(des==NULL && src==NULL)
{
    return NULL;
}
//先把des 一开始的地址记录起来
char *start=des;
// while(*src!='\0')
// {
    // //写法1:
    // // *des=*src;
    // // des++;
    // // src++;
    
    // //写法2:
    // *des++=*src++;
// }

while((*des++=*src++)!='\0'); //先复制在判断

*des='\0'; //拷贝完记得,加上结束标识符
return start;
}
char *myStrncpy(char *des,char *src,int count)
{
if(des==NULL && src==NULL)
{
    return NULL;
}
//先把des 一开始的地址记录起来
char *start=des;

while(*src!='\0' && count >0)
{
    *des++=*src++;
    count--;
}

if(count){
    while(count)
    {
        *des++='\0';
        count--;
    }
    return des;
}

*des='\0'; //拷贝完记得,加上结束标识符
return start;
}

int main()
{
    //char str[100]={'\0'};
    char *str;
    str = (char*)malloc(100);
    
    char *p="megniDXASDFA";
    //myStrcpy(str,p);
    myStrncpy(str,p,20);
    puts(str);
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    // int *p;
    // p=(int *)malloc(1); // 给指针p 分配内存空间,防止野指针
    // *p=11;
    // printf("1 %d\n",*p);
    // free(p);
    // printf("2 %d\n",*p);
    
    char *str;
    str=(char*)malloc(5);
    int len1=strlen("mxmxdhljkdadsadadadsada");
    printf("扩容前地址 -- %p\n",str);
    int moreLen=len1-5+1; // +1 -- '/0'
    realloc(str,moreLen);
        printf("扩容后地址 -- %p\n",str);
    strcpy(str,"mxmxdhljkdadsadadadsada"); //越界了
    puts(str);
    
    
    return 0;
}


assert(断言)


-- if else 的替代品:
用法:
include<assert.h>
 assert(expression);
作用: 计算表达式experrsion的值,if为假,他的stderr打印一条错误信息,通过aboor来终止程序运行

//报错信息

Assertion failed!

Program: D:\All_for_code\code_of_c\a.exe
File: stringT2.c, Line 7

Expression: des!=NULL && src!=NULL

===================================================

strcat -- 字符串拼接


原型: char  *strcat(char *dest,const chatr *src);
将src所指向的字符串复制到 dest所指向的字符串后面,(删除dest末尾的‘\0’),请确保dest足够长,返回指向dest的指针


#include<stdio.h>
#include<string.h>
#include<assert.h>
char *myStrcat(char *des,char *src)
{
    assert(des!=NULL && src!=NULL);
    
char* start=des;    
    
    while(*des != '\0')
    {
        des++;
        }
    while((*des++ = *src++)!='\0');
    *des='\0';
    
    return start;
    
}


char *myStrcat2(char *des,char *src)
{
    char *start=des;
    strcpy(des+strlen(des),src);
    return start;
    
}
int main()
{
    char str[50]="merngxoiangege";
    char *p;
    char *p2=" hamesome";
    p=myStrcat2(str,p2);
    puts(p);
    puts(str);
    return 0;
}

===================================================


strcmp --字符串比较 -- 主要判断是否相等



原型: int strcmp(const int*s1,const int* s2) --
返回值: // 字符比较大小遵循字典数 -- 比较完前面的,才比较后面的
 s1 = s2 返回0 
 s1 > s2 返回正数 -- 1
s1<s2  返回负数   -- -1


strncmp -- 只比较前n个字节

#include<stdio.h>
#include<string.h>

int myStrcmp(char *str1,char *str2)
{
    int res=0;
    int n1,n2;
    char *sta1=str1;
    char *sta2=str2;
    while(*str1&&*str2&&(*str1==*str2))
    {
        str1++;
        str2++;
    }
    if( *str1|| *str2)
    {
        str1=sta1;
        str2=sta2;
      while(*str1)
      {
        n1+=*str1;
        str1++;
      }        
        while(*str2)
      {
        n2+=*str2;
        str2++;
      }            
        
    }    
    
    res=n1-n2;
    if(res>0)res=1;
    else if(res<0) res=-1;
    else res=0;
    
    return res;
    
}


int main()
{
    char *p1="mengxiangjunb";
    char *p2="mengxiangjunb";
    int res = myStrcmp(p1,p2);
    printf("%d\n",res);
    
    
    return 0;
}


===================================================
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/778326.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ZK友好代数哈希函数安全倡议

1. 引言 前序博客&#xff1a; ZKP中的哈希函数如何选择ZK-friendly 哈希函数&#xff1f;snark/stark-friendly hash函数Anemoi Permutation和Jive Compression模式&#xff1a;高效的ZK友好的哈希函数Tip5&#xff1a;针对Recursive STARK的哈希函数 随着Incrementally Ve…

使用 react-router-dom v6.22 的 useRoutes 路由表

使用 react-router-dom v6.22 的 useRoutes 路由表 React Router 是 React 应用程序中用于导航的重要库之一。在 v6.22 版本中&#xff0c;它引入了 useRoutes 钩子&#xff0c;使得路由配置更加灵活。本文将介绍如何在 React 应用程序中使用 useRoutes 钩子来管理路由。 安装…

春秋云境CVE-2023-7130

简介 College Notes Gallery 2.0 允许通过“/notes/login.php”中的参数‘user’进行 SQL 注入。利用这个问题可能会使攻击者有机会破坏应用程序&#xff0c;访问或修改数据. 正文 这关有我用了两种办法&#xff0c;第一种是用报错注入进行手注&#xff0c;第二种就是sqlmap…

卡特尔16pf性格测试的用途,HR招聘测评和求职面试测评

卡特尔16pf性格测试&#xff0c;由美国心理学家卡特尔创建&#xff0c;通常简称为16pf&#xff0c;也叫16种人格因素&#xff0c;卡特尔把人格特征提取出16种特性&#xff0c;每种特性的不同并共同组合成丰富各异的人群。 而这16种人格因素&#xff0c;也常常被用于企业人力资…

Flask后端框架搭建个人图库

Hello&#xff0c;我是"小恒不会java" 前言 最近发现自己有一些站点图片丢失&#xff0c;原来是用了人家的链接。考虑到使用对象存储容易被刷流量&#xff0c;可以用flask这种轻量级框架快速实现网页登陆操作&#xff0c;行&#xff0c;也就不考虑正式生产环境那些复…

springcloud微服务项目,通过gateway+nacos实现灰度发布(系统不停机升级)

一、背景 灰度发布的目的是保证系统的高可用&#xff0c;不停机&#xff0c;提升用户体验。在微服务系统中&#xff0c;原有系统不下线&#xff0c;新版系统与原有系统同时在线&#xff0c;通过访问权重在线实时配置&#xff0c;可以让少量用户先应用新版本功能&#xff0c;如…

【vue核心技术实战精讲】1.9 Vue指令之v-model双向数据绑定

文章目录 前言 本节内容1、v-modelv-model 双向的数据绑定双向数据流&#xff08;绑定&#xff09; v-bind 和 v-model 的区别?input v-model"name"input :value"name"v-model: 其的改变影响其他 v-bind: 其的改变不不影响其他v-bind就是对属性的简单赋值…

如何使用 ArcGIS Pro 制作三维建筑

三维地图已经逐渐成为未来地图的趋势&#xff0c;对于大范围应用&#xff0c;只需要普通的建筑体块就行&#xff0c;如果有高程数据&#xff0c;还可以结合地形进行显示&#xff0c;这里为大家介绍一下 ArcGIS Pro 制作三维建筑的方法&#xff0c;希望能对你有所帮助。 数据来…

睿尔曼超轻量仿人机械臂之复合机器人底盘介绍及接口调用

机器人移动平台是一个包含完整成熟的感知、认知和定位导航能力的轮式机器人底盘产品级平台&#xff0c;产品致力于为各行业细分市场的商用轮式服务机器人提供一站式移动机器人解决方案&#xff0c;让合作伙伴专注在核心业务/人机交互的实现。以下是我司产品双臂机器人以及复合升…

在安卓手机上用termux安装完整kali linux的办法

在安卓手机上termux是完整的Linux仿真器&#xff0c;但也有时候需要在手机上装其他集成度更高的Linux发行版的刚需。 在安卓手机上用termux安装完整kali linux的办法&#xff0c;如下&#xff1a; pkg install wget openssl-tool proot tar -y && hash -r &&…

Rust编程(四)PackageCrateModule

这一部分的中文教程/文档都很混乱,翻译也五花八门,所以我建议直接看英文官方文档,对于一些名词不要进行翻译,翻译只会让事情更混乱,本篇从实战和实际需求出发,讲解几个名称的关系。 Module & Crate & Package & Workspace 英文中的意思: Cargo:货物 Crate:…

【详细讲解PostCSS如何安装和使用】

&#x1f308;个人主页:程序员不想敲代码啊&#x1f308; &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f3c6; &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d; 希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提…

Python读取csv文件入Oracle数据库

在Python中&#xff0c;使用pandas库的read_sql_query函数可以直接从SQL查询中读取数据到DataFrame。而pd.set_option函数用于设置pandas的显示选项。具体来说&#xff0c;display.unicode.ambiguous_as_wide选项用于控制当字符宽度不明确时&#xff0c;pandas是否将这些字符显…

go中继承、多态的模拟实现

Go语言采用了与传统面向对象编程语言&#xff08;如Java或C&#xff09;不同的方法来实现继承和多态。 它通过接口&#xff08;Interfaces&#xff09;、结构体&#xff08;Structs&#xff09;和组合&#xff08;Composition&#xff09;提供了继承和多态的能力 继承的模拟实…

在 Mac 上恢复已删除文件的 4 种方法 [完整指南]

几乎每个 Mac 用户都有过因删除、格式化硬盘或清空垃圾箱而导致数据丢失的经历。当您在 Mac 上删除文件并清空垃圾箱或使用“磁盘工具”擦除功能擦除整个硬盘驱动器时&#xff0c;您可能会认为已删除的文件或已擦除的数据已永远消失。事实上&#xff0c;事实并非如此。使用正确…

dou音全系纯算

先说明一个事情&#xff1a; 公众号开通了朋友们&#xff0c;大家可去关注一下&#xff0c;关于国内外的验证系列&#xff0c;或是另类常见的算法都有详情介绍的文章&#xff01;&#xff01;&#xff01;&#xff01;以后有问题可以直接在vx上留言&#xff0c;这样也方便看的多…

【ARM 嵌入式 C 入门及渐进 13 -- ARM 带返回值的汇编函数】

请阅读【嵌入式开发学习必备专栏 】 文章目录 在 ARMv8 架构中&#xff0c;系统寄存器的访问通常使用专有的指令。对于 MPIDR_EL1&#xff08;多处理器亲和性寄存器&#xff09;&#xff0c;可以使用 MRS&#xff08;Move System Register&#xff09;指令将其值读取到一个通用…

智能工具管理系统-智能工具柜系统

智能工具管理系统-智能工具柜系统 智能工具可视化管理系统(智工具DW-S308)是依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID工具进行统一管理、分析的信息化、智能化、规范化的系统。 一、工具管理现状 东识RFID工具管理系统是一种便捷化的工具…

jQuery如何获取元素宽高?

在jQuery中&#xff0c;获取元素的宽和高有多种方法&#xff0c;取决于你是否需要包括边框、内边距或其他额外空间。以下是几种常用的方式&#xff1a; 获取元素内容区域的宽和高&#xff08;不包括边框和内边距&#xff09;&#xff1a; var width $(#yourElement).width(); …

前端基础知识html

一.基础标签 1.<h1>-<h6>:定义标题&#xff0c;h最大&#xff0c;h最小 2.<font>&#xff1a;定义文本的字体&#xff0c;尺寸&#xff0c;颜色 3.<b>&#xff1a;定义粗体文本 4.<i>&#xff1a;定义斜体文本 5.<u>&#xff1a;定义文本下…