C语言中字符串的两种定义方式详解

目录
  • 方式1
  • 方式2
  • 总结

我们知道C语言中是没有字符串这种数据类型的,我们只能依靠数组进行存储,即字符数组,而我们定义并且初始化数组有两种方式。下面将给大家介绍这两种方式并且介绍这两种方式的区别:

方式1

前两种是正确的定义方式,第一种之所以没有指定字符数组长度的原因是编译器能够自己推断出其长度,无需程序员自己设定,这也是我们比较推荐的一种定义方式,但注意内存长度编译器一经判定就无法再次更改,接下来我们分析一下第三种编译器为什么会出现乱码。

相信大家都知道,字符串是以'\0'字符为结束标志的,这个标志本身也占用一个内存,我们在输出的时候是看不到这个字符的,这是由编译器所决定的,因为编译器的符本身占用了一个字节,所以sizeof()这个关键字在计算数组所占内存时要比字符多一个,如图中的arr1和arr2,而在计算arr3时,结果只有5,但输出和图二中我们所看到的却不止5个字符,那么这是为什么呢?

今天想给大家树立一个概念,我们在定义一个变量时,前面的类型加变量名实际上这是在内存中开辟了一个空间,变量所占内存的大小不是由变量的值所决定的,而时由我们最初开辟的空间的大小所决定的。这是一个很容易被大家忽视的一个小小的概念,希望大家能够牢记这一概念。

int a = 0;//在内存中开辟了一段4个字节的空间,然后将0的二进制补码形式(0的补码是其本身)放入到这段内存空间中
char b = 'c';//在内存中开辟了一段一个字节的空间,然后将字符'c'所对应的ascii码值所对应的二进制补码形式放入到这段内存空间中
//至于数组形式实际和这个是类似的,就是先开辟好数组所占的内存,然后将所要存储的数据的二进制补码形式放入到内存空间中

相信大家对上述原因已经有了属于自己的一些了解,接下来跟大家谈一下为什么数组arr3会输出乱码,'\0'是字符串的结束标志,但这个结束标志究竟有什么用呢?用处有两点,第一点是strlen函数在计算字符串所占内存空间时,遇到'\0'就会停止,进而能够求得字符串的长度(当然,这个计算不会把'\0'结束标志计算在内);第二点是编译器在执行printf函数时,以字符串形式进行输出字符数组时,遇到'\0'编译器就会停止输出,在arr3中,我们开辟的内存空间中放满了字符,没有字符串结束标志'\0',所以编译器会在把内存空间中的字符输出完并不会停止,还会继续进行输出,直到出现'\0'为止。

sizeof()计算的是变量所占的内存空间的大小,即红色框内的内存大小,也就是我们定义的大小,而strlen()计算的是从变量内存起始位置开始,一直向后进行计算,直到遇到结束标志'\0'为止,即上图中红色的框,下面给大家代码展示一下。

相信大家已经有所了解,这也能够方便我们更好的理解第二种定义方式所遇到的问题。

方式2

上述三种定义方式中1和3是正确的,方式2中并未把结束标志'\0'放入到数组最后一个空间中,这也是我们常犯的一个错误,希望大家要牢记,在采用这种方式对字符串进行定义时,不要忘记加上字符串的结束标志'\0',因为编译器不会为程序员自动添加'\0',所以我们并不推荐这种方式来对字符串进行定义,除了加上'\0'之外,另一种方式就是限定字符串长度,限定之后编译器会在末尾加上结束标志'\0'(此处只是指的vs2019编译器,其它编译器笔者并未验证),当然,最推荐的还是程序员手动添加'\0'作为结束标志。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 超详细的c语言字符串操作函数教程

    目录 一,常量指针与指针常量 二,字符串长度问题 三,c语言中的字符串拷贝函数 1) strcpy() 2), strncpy() 3), strcat() 4), strncat() 5), strcmp() 6), strncmp() 7), sprintf() 8) sscanf() 9) strchr() 10), strstr() 11) strtok() 总结 我们知道,c/c++之所以使用起来灵活,很大原因归因于它能够它对能够对内存的直接操作,所以本文我主要讲述一下c中的字符串操作

  • 一篇文章教你用C语言模拟实现字符串函数

    目录 前言 模拟 1.strlen 函数 2.strcpy 函数 3.strcat 函数 4.strcmp函数 5.strncpy函数 6.strncat函数 7.strncmp函数 8.strstr函数 9.strtok函数 总结 前言 编程过程中经常会使用到一些字符串函数,这些字符串函数都在C语言标准库中,我们可以直接使用.但我们也要了解一下它们是如何实现的. 模拟 1.strlen 函数 strlen函数是用来求字符串长度的.官方给出的解释如图 返回值类型是无符号整型,参数类型是char*

  • 一篇文章带你了解C语言的一些重要字符串与内存函数

    目录 一.字符串函数 1. 求字符串长度的strlen 2.比较字符串大小的strcmp 3.复制字符串的strcpy 4.追加字符串的strcat 5.查找字符串函数的strstr 二.内存函数 1.复制 memcpy,memmove 2.比较 memcmp 总结 一.字符串函数 1. 求字符串长度的strlen size_t strlen ( const char * str ); 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '

  • C语言的变量与常量 字符字符串与转义字符详解

    目录 一.变量 1.1定义变量的方法 1.2变量的分类 1.3变量的使用 二.常量 2.1字面常量 2.2 const修饰的常变量 2.3#define定义的标识符常量 2.4 枚举常量 三.字符和字符串 3.1 定义 3.2字符串的应用 3.3转义字符 四.注释 总结 一.变量 1.1定义变量的方法 如图中所示,变量可被定义为各种数据类型,如int 整型 char字符数据类型,short短整型,float单精度浮点数,double双精度浮点数等等.一般在变量定义后,需给变量赋值,如图中对所有变

  • C语言字符串数组详解

    C语言字符串数组 字符串是连续的字符序列,最后以空字符'\0'作为终止符.一个字符串的长度指所有字符的数量,但不包括终止符.在 C 语言中,没有字符串类型,自然也就没有运算符以字符串为操作数. 字符串被存储在元素类型为 char 或宽字符类型数组中(宽字符类型指 wchar_t.char16_t 或 char32_t).宽字符组成的字符串也称为宽字符串(wide string). C 标准库提供了大量的函数,它们可以对字符串进行基本操作,例如字符串的比较.复制和连接等.在这些传统的字符串函数以外

  • C语言中字符串的两种定义方式详解

    目录 方式1 方式2 总结 我们知道C语言中是没有字符串这种数据类型的,我们只能依靠数组进行存储,即字符数组,而我们定义并且初始化数组有两种方式.下面将给大家介绍这两种方式并且介绍这两种方式的区别: 方式1 前两种是正确的定义方式,第一种之所以没有指定字符数组长度的原因是编译器能够自己推断出其长度,无需程序员自己设定,这也是我们比较推荐的一种定义方式,但注意内存长度编译器一经判定就无法再次更改,接下来我们分析一下第三种编译器为什么会出现乱码. 相信大家都知道,字符串是以'\0'字符为结束标志的,

  • C语言中栈的两种实现方法详解

    目录 一.顺序栈 二.链式栈 总结 一.顺序栈 #include<stdio.h> #include<stdlib.h> #define maxsize 64 //定义栈 typedef struct { int data[maxsize]; int top; }sqstack,*sqslink; //设置栈空 void Clearstack(sqslink s) { s->top=-1; } //判断栈空 int Emptystack(sqslink s) { if (s-

  • jQuery中JSONP的两种实现方式详解

    前台代码如下: 后台Action代码如下: 运行后就可以看到结果了.我追踪了下后台ProcessCallback代码,如下图: 可以看到jsonCallback的值为"jQuery17104721....",它是前端传给远程服务器后台Action的.这里 jQuery171..表示的是jQuery的版本,可以简单地将这个理解为JSONP类型请求回调函数,jQuery在我们每次指定Ajax请求方式为 JSONP时都会生成这么一个JSONP回调函数.虽然jQuery会自动帮我们生成一个回调

  • Thinkphp事件机制两种实现方式详解

    目录 一.通过监听 二.通过订阅 1.创建订阅类 2.配置监听 3.触发监听 4.处理监听逻辑 4.1 自动绑定 4.2 手动绑定 总结 事件机制的实现有两种途径:通过监听.通过订阅 一.通过监听 1.创建监听类:在命令行模式下进入框架根目录执行 php think make:listener <自定义的类名> 例如: php think make:listener UserListener 执行之后将在<框架根目录>\app\listener\下生成UserListener这个类

  • 基于String变量的两种创建方式(详解)

    在java中,有两种创建String类型变量的方式: String str01="abc";//第一种方式 String str02=new String("abc")://第二种方式 第一种方式创建String变量时,首先查找JVM方法区的字符串常量池是否存在存放"abc"的地址,如果存在,则将该变量指向这个地址,不存在,则在方法区创建一个存放字面值"abc"的地址. 第二种方式创建String变量时,在堆中创建一个存放&q

  • keras 两种训练模型方式详解fit和fit_generator(节省内存)

    第一种,fit import keras from keras.models import Sequential from keras.layers import Dense import numpy as np from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import OneHotEncoder from sklearn.model_selection import train_test_s

  • Spring中Bean的三种实例化方式详解

    目录 一.环境准备 二.构造方法实例化 三.分析Spring的错误信息 四.静态工厂实例化 4.1 工厂方式创建bean 4.2 静态工厂实例化 五.实例工厂与FactoryBean 5.1 环境准备 5.2 实例工厂实例化 5.3 FactoryBean的使用 六.bean实例化小结 一.环境准备 准备开发环境 创建一个Maven项目 pom.xml添加依赖 resources下添加spring的配置文件applicationContext.xml 最终项目的结构如下: 二.构造方法实例化 在

  • Java中Singleton的3种实现方式详解

    一.什么是Singleton? <设计模式>的作者.Eclipse和 Junit 的开发者 Erich Gamma 在它的理论体系中将 Singleton 定义为仅仅被实例化一次的类.在当今面向对象程序的实际开发中,Singleton 通常被用来代表一个无状态的对象,例如函数和那些本质上唯一的系统组件. 值得注意的是,使类成为 Singleton 会使得它的客户端测试变得非常困难,因为我们不可能给Singleton替换模拟实现,除非我们实现一个充当其类型的接口. 实现 Singleton 有三

  • Java动态代理的两种实现方式详解【附相关jar文件下载】

    本文实例讲述了Java动态代理的两种实现方式.分享给大家供大家参考,具体如下: 一说到动态代理,我们第一个想到肯定是大名鼎鼎的Spring AOP了.在AOP的源码中用到了两种动态代理来实现拦截切入功能:jdk动态代理和cglib动态代理.两种方法同时存在,各有优劣.jdk动态代理是由java内部的反射机制来实现的,cglib动态代理是通过继承来实现的,底层则是借助asm(Java 字节码操控框架)来实现的(采用字节码的方式,给A类创建一个子类B,子类B使用方法拦截的技术拦截所以父类的方法调用)

  • Django中提供的6种缓存方式详解

    前言 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回. Django中提供了6种缓存方式: 开发调试 内存 文件 数据库 Memcache缓存(python-memcached模块) Memcache缓存(pylibmc模块) 1.配置

随机推荐