C语言程序设计

1、C语言基础

1.1概述

  1. C是一种通用的计算机程序设计语言,目前用于编写系统软件和嵌入式应用开发。C语言是由系列函数组成,这种结构便于将大型程序分成若干个相对独立的模块并分别实现,程序运行时通过函数调用来完成功能要求。 一个函数必须有一个main函数,整个程序的执行,从该函数开始执行。

1.2数据类型

C语言的数据类型可分为:基本数据类型(内置的类型)和复合数据类型(用户自定义的类型)

  1. 基本数据类型 :字符型(char)、整型(int)、浮点型(float、double);void也是一种基本类型,void不对应具体的值,而是用于一些特定的场景,例如定义函数的参数类型、返回值、函数中指针类型等说明,表示没有或还没确定类型;C语言的数据变量、常量表示,他们都有具体的类型属性。
    变量存储数据的内存单元,变量分定义是为了为变量分配存储空间,还可以为变量指定初始值;在一个C程序中,一个变量只有一个定义;在一个C程序文件中需要引用其他程序文件中定义的变量时,就需要进行声明;变量声明用来表示变量分类型和名字,当定义变量时既声明了它的类型和他的名字,可以通过使用extern关键字声明变量名。
    字面量:数据在源程序中直接以值形式呈现,在程序运行中不被修改,表现为整型、浮点型、字符变类型;默认情况下,整型字面量以十进制形式表示,前缀为0x或0X表示十六进制常数;同样,一个整型常数也可以加U或u后缀,指定为unsigned类型;浮点型字面量总是默认为double型,除非有字母F或f后缀,才被认为为float型,若有后缀L或l则被处理成为long double型;实型常量也可以表示成指数形式**,例如0.0001可以表示成1.0E-3或1.0e-3,其中e或E表示指数;字符字面量用一对单引号括起来,对于不能打印的特殊字符,可以用他们的编码指定,还有一些转义字符。
    常量:常量修饰符const的含义是其所修饰对象的为常量,若一个变量被修饰为const,则该变量值就不能被其他语句修改。
    标识符和名字的作用域:在C语言程序中使用变量名、函数名、符号、以及用户定义数据类型名统称为标识符,除库函数的函数名由系统定义外,其余都由用户自定义;标识符命名规则如下:⒈标识符必须以字母a-z、A-Z或下划线开头后面可以跟任意字符,这些字符可以是字母、下划线和数字,其他字符不允许出现在标识符中;⒉标识符区分大小写字母;⒊标识符的长度在C89标准中规定31个字符内,在C99标准中规定63个字符以内;⒋c语言中的关键字(保留字)有特殊意义,不能作为标识符;⒌标识符最好使用具有一定意义的字符串,便于记忆和理解,变量名一般用小写字母,用户自定义类型名的开头用字母大写;通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域,同一个名字在不同的作用域可能表示不同的对象;作用域可分为:全局作用域、块作用域(局部的)之分,作用域可以嵌套,尽可能将变量定义在最小的作用域内,并为其设置初始值。
  2. 字符、字符数组、与字符串
    数组:数组是一种集合类型数据,他由多个元素组成,每个元素都有相同的数据类型,占有相同大小的存储单元,并且在内存中连续存放;每个数组有一个名字,数组中的每一个元素有一个序号(称为下标),表示元素在数组中的位置,数组的维数和大小在定义的数组中确定,程序运行时不能改变。按维度有一维数组和二维数组。可以用sizeof函数计算数据空间大小,即字节数。
    字符串数组与字符串:当数组中的元素由字符串组成,便称为字符数组。字符串是一个连续的字符序列,用特殊字符**‘\0’结尾;数组的每一个元素保存字符串的一个字符,并附加一个空字符,表示为‘\0’,添加在字符串的末尾,以标识字符串结束;如果字符串有n个字符,则至少需要长度为n+1**的字符数组来保存它;一个字符串常量常用一对双括号括起来,编译系统自动在每一个字符串常量的末尾增加‘\0’;字符串可以由任意多个字符组成,一个长字符串可以占两行或多行,但在最后一行的各行需要用反斜杠结尾;需要注意的是:‘A’和“A”是不同的,“A”是由两个字符组成(由字符A和\0组成),而‘A’只由一个字符组成(由A组成),最短的字符串是“”空字符串,它由一个结尾符‘\0’组成。
  3. 枚举类型:枚举就是把这种类型数据可取得值逐一列举出来;枚举类型是一种用户定义的数据类型。其中,“枚举类型名”右边的花括号中的内容称为枚举表,枚举表中的每一项称为枚举成员,枚举成员是常量,枚举成员之间用逗号分割开来,整型常数是枚举成员的初始值;如果没有为枚举成员付初始值,编译系统为每个枚举成员赋予一个不同的整型值,第一个成员为0,第二个成员为1,依次类推;当枚举类型中的某个成员赋值后,其后的成员依次加一的。
  4. 结构体、共用体和typedef
    ①结构体:利用结构体类型可以把一个数据元素的各个不同的数据项聚合为一个整体。声明格式为:
    struct 结构体名{
    结构体列表
    }变量名列表;
    可以用typedef关键字为结构体定义结构体类型命名;一个结构体变量分存储空间长度等于所有成员占空间长度之和。
    ②共用体类型:公用体类型的声明格式为:union 公用体名{
    成员列表
    }变量名列表。
    一个共用体变量分存储空间的大小等于其占用最大的成员的大小,所有的成员变量占用同一段内存空间。

1.3运算符与表达式

C语言提供了丰富的运算符,包括算数运算符、关系运算符、逻辑运算符、位运算符、条件运算符、赋值运算符、逗号运算符和其他运算符。根据运算符的操作数的个数,可分为:单目运算符(一个操作数)、双目操作符(两个操作数)和三目运算符(3个操作数)表达式:由运算符和操作数组成,他规定数据对象的运算过程。

  1. 自增(++)与自减(–)运算符:运算符的作用是将数值变量分值加1或减少1。自增或自减运算符只能作用于变量而不能作用于常量或表达式。++value称为前缀方式,value++称为后缀方式,其区别是:前缀先把变量的值增1,然后取变量的新值与表达式的运算;后缀先取变量的值与表达式的运算,然后再将变量的值增加1
  2. 关系运算符:关系运算符用于数值之间的比较,包括等于(==)、不等于(!=)、小于(<)、小于或等于(<=)、大于(>)、大于或等于(>=),结果的值为1(表示关系成立)或0(表示关系不成立)。不能用于关系运算符对字符串进行比较,因为被比较的不是字符串的内容本身,而是字符串的地址
  3. 逻辑运算符:逻辑与(&&)、逻辑或(‖)、逻辑非(!)的运算结果为1(表示true)或者为0(表示为false)。“逻辑非”是单目运算符,它将操作数取反;“逻辑与”是双目运算符。
  4. 赋值运算与组合运算:赋值运算符(=)的作用是将一个表达式的值赋给一个变量,可进行组合赋值。
  5. 条件运算符和逗号运算符:①条件运算符是C中唯一的三目运算符,也称三元运算符,他有三个操作数;②多个表达式可以用逗号组合成一个表达式,即逗号运算符,逗号运算符带两个操作数,结果是右操作数。
  6. 位运算符:位运算要求操作数是整型数,并按二进制位的顺序处理他们。C/C++提供6种位运算符:①∽ 取反;②& 逐位与 ;③|逐位或;④^ 逐位异或;⑤<<逐位左移;⑥>>逐位右移。赋值运算符也可以与位运算符组合,产生&=、|=、^=、>>=、<<=等组合运算符。
  7. sizeof:用于计算表达式或数据类型的字节数,其运算结果与系统相关。
  8. 类型转换:在混合数据类型的运算过程中,系统自动进行类型转换。在程序中也可以进行数据类型的强制转换

1.4输入/输出

C程序中输入/输出操作都由输入/输出标准库函数(在头文件stdio.h中声明)完成,常见的有格式输出函数printf和格式化输入函数scanf,以及文件操作函数fopen、fprintf和fscanf等。

  1. printf:printf函数称为格式输出函数,其功能是按照用户指定格式,将指定的数据输出到显示屏幕上。printf函数调用一般格式为:printf(“格式控制字符串”,输出列表),其中格式控制字符串用于指定输出格式,由格式说明普通字符组成;格式说明以**%开头**,其后是各种格式字符,以说明输出格式的类型、形式、长度、小数位数等;普通字符按照原样输出,在显示中起提示作用;输出列表中给出了各个输出项,要求格式字符串和各输出项在数量和类型一一对应。如果在“%”后为“-”表示输出结果左对齐(在规定输出长度的情况下,默认为右对齐),如果在“%”后为“+”,表示输出数值的符号(正号或负号)。
  2. scanf:scanf函数称为格式输入函数,即按用户指定的格式从键盘把数据输入指定变量中。scanf函数调用一般格式为:scanf(“格式字符串”,地址列表),其中格式字符串的作用与printf函数相同,但不需要普通字符;地址列表中给出各变量分地址,即由地址“&”后跟变量名组成;变量的地址是C编译系统分配的,用户不必关心具体的地址是多少;在地址列表中的每个int、double、或char型变量前都有一个“&”,而以串格式输入一个字符串到字符数组时,仅需给出数组名(不用加“&”,因为数组名是表示数组空间首地址的地址常量);逗号用于分隔变量名称;占位符的顺序必须与地址列表中变量分顺序一致。

2、控制语句

语句是程序设计语言的一种基本单位,编程时使用语句描述运算和控制过程;基本的流程控制结构有顺序分支(选择)、循环3种,C语言的流程控制语句有if、switch、for、while、do-while、break、continue、return等。

2.1选择语句

  1. 选择语句:表示分支(选择)结构的语句有if、switch语句。
    if语句:if语句用于表达根据一定的条件在两条流程中选择一条执行的情况。
    switch语句:switch语句用于表示从多分支的执行流程中选择一个来执行;switch的执行过程是:首先计算表示式的值,然后自上而下地将其结果依次与每一个常量表达式进行匹配,如果匹配成功,就执行该常量表达式后的一系列语句,当遇到break时,就结束switch语句的执行,否则顺序执行到花括号最后一条语句,default是可选择的,如果没有常量表达式的值与表达式的值匹配,则执行default语句,需要注意的是,表达式的值必须是字符型或整型

2.2循环语句

  1. 循环语句:C语言循环语句有while、do-while、和for。
    while:while语句的含义是首先计算表达式的值,如果其值不为0(即为真),就执行“循环体语句”,这个过程重复执行,直到“表达式”的值为0(即为假)时结束循环。
    do-while:do-while语句是先执行循环体语句,再计算表达式,如果表达式的值不为0,则继续执行循环语句,否则终止循环。
    for:先计算表达式1,然后是表达式2,如果表达式2不为0则执行循环体语句,否则终止循环,最后计算表达式3,重复表达式2和3。

2.3break语句

  1. break语句:break语句用在switch语句中,用于跳出switch语句,结束switch的执行;break语句在循环语句中的作用是终止并跳出当前循环语句

2.4continue语句

  1. continue:continue语句的功能和break不同,他是结束当前这一次循环,转而执行下一次循环;在循环体中,continue语句执行之后,循环体内的语句不在执行。

2.5return语句

  1. return:return语句用于函数返回值。

3、函数

函数是一个功能模块,用来完成特定的任务。在程序设计时,把一个复杂的大程序分成若干个子程序,函数就是C程序的子程序。
有两种函数,一种是已定义并随着编译系统的发布、可供用户调用的标准函数,也称为库函数,如printf、scanf等;另一种是用户根据需要自己定义的。

3.1函数定义

  1. 函数定义包括以下几个部分:函数名、参数列表、返回类型和函数体。一个函数中可以有多个return语句,在函数执行过程中,遇到一个return语句将立即停止函数执行,并返回到调用函数。

3.2函数声明

  1. 如果一个函数调用另一个函数,在调用函数中必须对被调用函数进行声明。
    可以将一些函数的声明集中放在头文件中,然后再用“#include”将头文件中包含在程序文件中,也可以放在程序文件的开头,而把程序的定义放在程序文件后面的某个地方。
    C程序是从main函数开始执行,而main函数在程序文件中的位置并没有特别的要求。

3.3函数调用

  1. ①:函数调用由函数名、和函数调用运算符“()”组成,“()”内有0个或多个逗号分隔开的参数;每一个实参是一个变量或表达式,且实参的个数与类型要与被调用函数定义的参数的个数和类型相互匹配;当被调函数执行时,首先先调用实参表达式,并将结果值传递给形参,然后执行函数体,返回值被传送到调用函数;如果函数调用后有返回值,函数调用可以用在表达式中,而无返回值的函数调用常常作为一个单独的语句使用;调用一个函数之前,必须对被调用函数进行声明。
  2. ②: C语言中的参数传递方式为值传递(地址也是一种值传递);函数在被调用以前,形参变量并不占用内存单元,当函数被调用时,才为形参分配内存空间,并将相应的实参值复制给形参,所以被调用函数在执行过程中修改的形参变量的值并不影响实参变量分值。
  3. :当数组作为函数参数时,调用函数中的实参数组只是传送该数组在内存中的首地址,即调用函数通知被调用函数在内存中的什么地方找到该数组;数组参数并不指定数组的个数,除传送数组名外,调用函数还必须将数组的元素的个数通知给被调用函数。
  4. :函数参数的引用传递不同于值传递。值传递是把实参赋值给到形参,实参和形参占不同存储单元,形参若改变值,不会影响到实参。而引用传递本质是:将实参的地址传递形参。以数组作为函数参数传递时,是引用传递方式,即把实参数组在内存中的地址首地址传递给形参。在被调用函数中,如果改变了形参数组中元素的值,那么在调用函数中,实参数组对应的元素值也会发生相应的改变。当数组作为函数参数时,仅仅传送数组在内存中的首地址,避免了复制每一个数组元素,从而节省内存空间和运行时间。

3.4递归函数

  1. 递归函数是指函数直接调用自己或通过一系列调用语句调用自己,是一种描述问题和解决问题的一种常用方法。
    递归过程的特点是:“先逐步深入,然后再逐步返回”;它有两个基本要素:边界条件和递归模式,边界条件确定递归到何时终止,也称递归出口递归模式表示大问题是如何分解为小问题,也称递归体。

4、指针

指针:是内存单元地址,它可能是变量分地址、数组的地址,或者是函数的入口地址。存储地址的变量称为指针变量,简称指针。

4.1指针的定义

指针类型的变量是用来存放内存地址的。指针的两个概念:指针对象和指针指向的对象指针对象:是明确命名的指针变量;指针指向的对象:是另一个变量,用“*”和指针变量联合表示。

  1. 空指针:C语言定义了一个标准预处理宏NULL(它的值为0,称为空指针常量),表示指针不指向任何内存单元。可以把NULL赋给任意类型的指针变量,以初始化指针变量;全局指针变量会被自动初始化为NULL,局部指针变量的初始化为随机的。编程时常见的一个错误是没有给指针赋初始值。未初始的指针可能是一个非法的地址,导致程序运行时出现非法指针访问错误,从而使程序异常终止。
  2. “&”和“*” :“&”称为地址运算符,其作用是获取变量分地址。“*” 称为间接运算符,其作用是获取指针所指向的变量。void*类型可以与任意类型匹配。void在被使用之前,必须转换为明确的类型。
  3. 指针与堆内存:在程序运行过程中,堆内存能够被动态地分配和释放,在C程序通过malloc(或calloc、realloc)和free函数实现该处理要求。因为内存资源是有限的,所以若申请的内存不在需要就及时释放。如果程序中存在未被释放的内存块,则称为内存泄露

4.2指针与数组

  1. 通过指针访问数组元素:在C程序中,常利用指针访问数组元素,数组名就是数组在内存中的首地址,即数组中第一个元素的地址。可以通过下标访问数组元素,也可以通过指针访问数组元素。数组名是常量指针,数组名的值不能改变。
    一般情况下,一个int型变量占4个字节的内存空间,一个char型变量占用一个字节的空间,所以str是字符针针的话,str++就使得str指向下一个字符;而整型指针ptr++则使得ptr指向下一个int型整数,即指向数组的第二个元素。
    可以用指针访问二维数组元素。由于二维数组元素在内存中是以线性方式存储的,并且按行存放,所以用指针访问二维数组的关键是如何计算出某个二维数组在内存中的地址。二维数组在内存中的地址应为数组空间首地址加上排列在数组之前的元素所占空间的偏移量。

  2. 通过指针访问字符串常量:可将指针设为指向字符串常量(存储在只读存储区域),通过指针读取字符串或其中的字符。不允许在程序运行过程中修改字符串常量。

  3. 指针数组:如果数组的元素类型是指针类型,则称为指针数组;若需要动态生成二维整型数组,则传统的处理方式是先生成一个指针数组,然后把每个指针初始化为动态分配的“行”。

  4. 指针运算:在C程序中,让指针变量加一个整数或减一个整数的含义与指针指向的对象有关,也就是与指针所指向的变量所占用存储空间大小有关。

  5. 常量指针与指针常量常量指针是指针指向的对象是常量,即指针变量可以修改,但是不能通过指针来修改其指向的对象。指针常量:是指针本身是个常量,不能再指向其他对象。 区分常量指针和指针常量的关键是:“*”的位置,如果const在“*”的左边,则为常量指针,如果const在“*”的右边则为指针常量,如果将“*”读作“指针”,将“const”读作常量,内容刚好符合。

4.3指针与函数

指针可以作为函数参数或返回值。

  1. 指针作为函数参数:①一般地址传参:用指针作为函数的参数可以在进行函数调用时,通过指针来改变调用函数中实参变量的值。如果在被调用函数中修改参数的值,则不能实现对实参变量的修改。②数组作为参数传递:本质是将数组的首地址传递给形参,在被调用函数中对数组元素的修改可以保留下来。使用const修饰的函数参数,可以避免被调用函数中出现不当的修改。如果要使指针参数在函数内不能修改为指向其他对象,则可用指针常量。
  2. 指针作为函数返回值:函数的返回值可以是一个指针。返回指针值得函数定义的一般格式为:数据类型* 函数名(参数列表)。
  3. 函数指针:在C语言程序中,可以将函数地址保存在函数指针变量中,然后用该指针间接调用函数。将函数地址赋值给函数指针时,其参数和类型必须匹配。

4.4指针与链表

指针是C语言的特色和精华所在,链表是指针的重要应用之一,创建、查找、插入、删除节点是链表上的基本运算,需要熟练掌握这些运算的实现过程,其关键是指针变量的初始化、和在链表节点之间的移动处理

  1. 以元素值为整数的单链表为例,需要先定义链表中的结点类型,下面将其名明为Node,而LinkList则是指向Node类型变量的指针类型名。
typedef  struct  node{
        int  data;//结点的数据域
        struct  node  *next;//结点的指针域
}Node,*LinkList;
Node a,b;
LinkList  p;//等同于Node  *p
a.data=1;
b.data=2;
p=&a;
p->data=10;//结果等同于a.data=10
p->next=&b;//结点a和b通过a.next链接起来

当p指向Node类型的节点时,涉及两个指针变量:p和p->next,p是指向结点的指针,p->next是结点中的指针域;运算“p=p->next”之后,p指向下一个节点;运算“p->next=p”之后,结点的指针域指向自己。

5、常见的C语言错误

编程时出现错误是难免的,程序错误一般可分为语法错误和语义错误两类,语法错误在编译阶段发现,出现这类错误时程序将不能运行。C程序中常见的语法错误包括引用了未定义的变量、缺少分号或括号等,语义错误种类比较多,如未将变量正确初始化、运算结果溢出、数组下标越界、函数调用的参数类型不匹配等。

5.1标识符大小写有区别

  1. 标识符的大小写有区别:C语言默认同一个字母的大写和小写形式代表不同的字符。习惯上,符号常量名用大写,变量用小写。

5.2忽略变量的类型导致的运算的不合法

  1. 忽略变量的类型导致的运算的不合法:%是整数取余运算,运算对象只能是整数。

5.3字符常量与字符串的混淆

  1. 字符常量与字符串常量的混淆:C语言中,字符常量是一由单引号括起来得得单个字符,字符串常量是一对双引号括起来的字符序列。C语言规定以“\0”作为字符串的结束标志,它是由系统自动加上的。

5.4引用未初始化

  1. 引用未初始化的变量:未初始化变量的值是随机的,使用这些数据会造成不可预料的后果。在声明变量时对其进行初始化是一个好的编程习惯。另外也要重视编译器的警告信心,发现在引用未初始化的变量时,立即进行修改。

5.5“=”与“==”

  1. “=”与“==”:在C语言中,“=”是赋值运算符,“==”是关系运算符

5.6少分号或多分号

  1. 分号是C语句中不可缺少分一部分,语句末尾必须是分号。

5.7 scanf和printf函数使用问题

  1. 调用scanf函数时地址列表中的变量缺少“&”。
  2. 调用scanf函数时输入数据的格式问题。输入数据时企图规定精度也是错误的。
  3. 调用printf函数时输出列表中的变量多写了“&”。
  4. 调用printf函数时,输出格式问题

5.8switch语句中的漏写break

  1. 由于case只起标识的作用,而不其判断作用。需要与break语句连总。

5.9数据溢出

  1. C程序中的数据都有类型属性,每一种类型数据都有其取值范围限制。因此,在程序执行过程中,若运算结果超出变量的取值范围,则由于溢出表现为运算结果错误。

5.10定长数组和变长数组

  1. 数组是程序中常见得数据结构,C程序中定义数组时应确定其维数和各维的大小(即定长数组),这是编译时就可确定数组的这些属性。
  2. 对于变长数组,并不是所有的C编译系统都支持。如果数组的大小需要在运行时确定,可采用动态内存申请的方法并用指针保存内存的地址,所有的C系统都支持这种方式。

5.11 数组下标的有限范围

  1. C语言规定,数组元素下标值由0开始,直到“元素个数”减一,引用数组元素时,以“元素个数”作为数组下标,会导致越界访问问题。
  2. 内存越界访问问题有两种:一种是读越界,即读取了不属于自己的数据,如果所读的内存地址是无限的,程度就会异常终止。如果读内存地址是有效的,在读的时候不会出问题,但由于读到的数据是随机的,使用该数据会有不了预期的效果。另一种是写越界,又称缓冲区溢出。所写入的数据是随机的,也会产生不可预期的后果。

5.12混淆数组名与指针变量

  1. 在C/C++语言中,数组名代表数组的首地址,它的值是一个常量,不能被修改。

5.13使用指针的常见问题

指针是C语言中最有力的武器,能够为程序员提供极大的编程灵活性,无论是变量指针还是函数指针,都应熟练掌握。使用指针时,可能遇到内存泄露、空指针引用问题。

  1. 内存泄露:在堆上分配的内存不在使用时,就应释放掉,以便提高内存空间的利用率。在C系统中,内存管理器不会自动回收不再使用的内存。如果在程序中没有释放不在使用的内存,这些内容就不能被重用,从而造成所谓的内存泄露。
    通常,上量的内存泄露不至于让程序崩溃,也不会出现逻辑错误,一般在进程退出时,系统会自动释放该进程所有相关的内存,所以不会产生严重的后果。但是内存泄露过多以至于内存耗尽而导致后续的内存分配失败时,程序可能崩溃。
    因此,编程时要注意malloc和free的配合使用。
  2. 空指针:空指针在C程序中有特殊的意义,通常用来判断一个指针的有效性。空指针一般定义为0。现代操作系统都会保留从0开始的一块内存,至于这块内存有多大,不同操作系统有不同的规定,一旦程序试图访问这块内存,系统就会触发一个异常。
    访问空指针指向的内存,通常会导致程序崩溃,或产生不可预料的错误。因此在访问指针指向的对象时,应确保指针不是空指针。
  3. 野指针:野指针是指那些已经释放掉的内存指针。释放的内存块会被内存管理器重新分配,此时,野指针指向的内存已经被赋予新的意义。对野指针所指向的访问,无论是有意义的还是无意义的,都可能产生不了预料的后果。在释放内存后立即把对应指针置为空值,这是避免野指针常用的方法。
  4. 返回指向临时变量的指针:在C程序中,函数中的参数和非静态的局部变量(自动变量)都在栈中分配存储空间,而栈中的变量是临时的。当函数执行完成时,相关的临时变量和参数所占用的空间都会被系统自动收回。不能把指向这些临时变量的指针返回给调用者。
  5. 试图修改常量:程序中使用的有些数据存储在常量区中,他们的值在程序运行过程中不被允许修改。
    若对一个变量定义使用const修饰符(即变量成为常数),则试图为变量重新赋值也会产生编译错误。
    若在函数参数前加上const修饰符,则编译器会禁止通过赋值修改这样的变量。但这并不是强制的,在程序中完全可以用强制类型转换绕过去,一般也不会出错。而对于全局常量和字符串常量,即使使用强制类型转换,运行时任然会出错。原因在于他们是放在常量区里面的,而常量区的内存页面其不可修改的。
  • 8
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值