c语言const与*位置关系,C语言程序的存储区域与const关键字的使用方法
四.程序中段的使用
C语言中的全局区(静态区),实际上对应着下述几个段:
只读数据段:R0 Data
读写数据段:RW Data
未初始化数据段:BSS Data
一般来说,直接定义的全局变量在未初始化数据区,如果该变量有初始化则是在已初始化数据区(RW Data),加上const修饰符将放置在只读区域(R0 Data).
eg:
const char ro[]=”this is a readonlydata”;//只读数据段,不能改变ro数组中的内容,ro存放在只读数据段。
char rw1[]=”this
is global readwrite data”;//已初始化读写数据段,可以改变数组rw1中的内容。应为数值是赋值不是把”this is
global readwrite data” 地址给了rw1,不能改变”this is global readwrite
data”的数值。因为起是文字常量放在只读数据段中
char bss_1[100];//未初始化数据段
const char *ptrconst =
“constant data”;//”constant
data”放在只读数据段,不能改变ptrconst中的值,因为其是地址赋值。ptrconst指向存放“constant
data”的地址,其为只读数据段。但可以改变ptrconst地址的数值,因其存放在读写数据段中。
int main()
{
short b;//b放置在栈上,占用2个字节
char a[100];//需要在栈上开辟100个字节,a的值是其首地址
chars[]=”abcde”;//s在栈上,占用4个字节,“abcde”本身放置在只读数据存储区,占6字节。s是一个地址常量,不能改变其地址数值,即s++是错误的。
char*p1;//p1在栈上,占用4个字节
char*p2 =”123456”;//”123456”放置在只读数据存储区,占7个字节。p2在栈上,p2指向的内容不能更改,但是p2的地址值可以改变,即p2++是对的。
static char bss_2[100];//局部未初始化数据段
static int c=0 ;//局部(静态)初始化区
p1 = (char *)malloc(10*sizeof(char));//分配的内存区域在堆区
strcpy(p1,”xxx”);//”xxx”放置在只读数据存储区,占5个字节
free(p1);//使用free释放p1所指向的内存
return 0;
}
说明:
1.只读数据段需要包括程序中定义的const型的数据
(如:const char ro[]),还包括程序中需要使用的数据如“123456”。对于const char
ro[]和const char * ptrconst的定义,它们指向的内存都位于只读数据据区,其指向的内容都不允许修改。区别在于前者不允许在程序中修改ro的值,后者允许在程序中修改ptrconst本身的值。对于后者,改写成以下的形式,将不允许在程序中修改ptrconst本身的值:
const char * const ptrconst = “const data”;
2.读写数据段包含了已经初始化的全局变量static char rw1[]以及局部静态变量static char
rw2[]。rw1和rw2的差别在于编译时,是在函数
内部使用的还是可以在整个文件中使用。对于前者,static修饰在于控制程序的其他文件时候可以访问rw1变量,如果有static修饰,将不能在其他
的C语言源文件中使用rw1,这种影响针对编译-连接的特性,但无论有static,变量rw1都将被放置在读写数据段。对于后者rw2,它是局部的静态
变量,放置在读写数据区;如果不使用static修饰,其意义将完全改变,它将会是开辟在栈空间局部变量,而不是静态变量。
3.未初始化数据段,事例1中的bss_1[100]和
bss_2[200]在程序中代表未初始化的数据段。其区别在于前者是全局的变量,在所有文件中都可以使用;后者是局部的变量,只在函数内部使用。未初始
化数据段不设置后面的初始化数值,因此必须使用数值指定区域的大小,
编译器将根据大小设置BBS中需要增加的长度。
4.栈空间包括函数中内部使用的变量如short b和char a[100],以及char *p1中p1这个变量的值。
1》变量p1指向的内存建立在堆空间上,堆空间只能在程序内部使用,但是堆空间(例如p1指向的内存)可以作为返回值传递给其他函数处理。
2》栈空间主要用于以下3类数据的存储:
a.函数内部的动态变量
b.函数的参数
c.函数的返回值
3》栈空间主要的用处是供函数内部的动态变量使用,变量的空间在函数开始之前开辟,在函数退出后由编译器自动回收
4.看一个事例:
#include
int main()
{
char*p =”tiger”;
p[1]=’I’;
p++;
printf(“%s\n”,p);
}
编译后提示:段错误
分析:
char *p
=”tiger”;系统在栈上开辟了4个字节存储p的数值。”tiger”在只读存储区中存储,因此”tiger”的内容不能改
变,*p=”tiger”,表示地址赋值,因此,p指向了只读存储区,因此改变p指向的内容会引起段错误。但是因为p是存放在栈上,因此p的数值是可以改
变的,因此p++是正确的。
五.const的使用
1.前言:
const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程序上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解被人的程序有所帮助。
2.const变量和 常量
(1)const修饰的变量,其值存放在只读数据段中,起值不能被改变。称为只读变量。
其形式为 const int a=5;此处可以用a代替5.
(2)常量:其也存在只读数据段中,其数值也不能被改变。其形式为”abc”,5.
3.const 变量和const限定的内容
先看一个事例:
#include
typedef char *pStr;
intmain()
{
char string[6] = “tiger”;
const char*p1 = string;
const pStr p2 = string;
p1++;
p2++;
printf(“p1=%s\np2=%s\n”,p1,p2);
}
程序经过编译后,提示错误为
error:increment of read-only variable ‘p2’
1>const 使用的基本形式为:const char m;
限定m 不可变
2>替换1式中的m,const char *pm;
限定*pm不可变,当然pm是可变的,因此p1++是对的。
3>替换1式中的char,const newType m;
限定m不可变,问题中的pStr是一种新类型,因此问题中p2不可变,p2++是错误的。
(3)const 和指针
类型声明中const用来修饰一个常量,有如下两种写法:
1>const在前面
const int nValue;//nValue是const
const char *pContent;//*pContent是const,pConst可变
const (char *)pContent;//pContent是const,*pContent可变
char *const pContent;//pContent是const,*pContent可变
const char * const pContent;//pContent和*pContent都是const
2>const 在后面与上面的声明对等
int const nValue; // nValue是const
char const * pContent;//*pContent是const, pContent可变
(char *) constpContent;//pContent是const, *pContent可变
char* const pContent;// pContent是const, *pContent可变
char const* const pContent;//pContent和*pContent都是const
说明:const和指针一起使用是C语言中一个很常见的困惑之处,下面是两天规则:
(1)沿着*号划一条线,如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。
(2)对于const (char *) ; 因为char *是一个整体,相当于一个类型(如char),因此,这是限定指针是const。
c语言const与*位置关系,C语言程序的存储区域与const关键字的使用方法相关推荐
- 位置关系C语言,C++/STL实现判断平面内两条线段的位置关系代码示例
概念 平面内两条线段位置关系的判定在很多领域都有着广泛的应用,比如游戏.CAD.图形处理等,而两线段交点的求解又是该算法中重要的一环.本文将尽可能用通俗的语言详细的描述一种主流且性能较高的判定算法. ...
- C语言程序的存储区域
由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段.编译过程把C语言文本文件生成汇编程序,汇编过程把汇编程序形成二进制机器代码,连接过程则将各个源文件生成的二进制机 ...
- c语言变量定义位置区别,C语言中变量定义的位置(C89和C99的区别)
C语言中变量定义的位置(C89和C99的区别) 在C++和JAVA中,按照语法,我们可以把变量定义在任何位置,所以很多人习惯了"哪里使用哪里定义"的这种做法,所以当用C语言进行编程 ...
- c语言编写单词位置反转,C语言笔试题答案.docx
C语言笔试题答案 C语言笔试题答案简答题程序的局部变量存在于(栈)中,全局变量存在于(静态区)中,动态申请数据存在于(堆)中.设有以下说明和定义:typedef union {long i; int ...
- c语言判断获取位置字符,C语言 · 判定字符位置
Linux终端打印命令使用介绍 常用linux打印命令 日常使用中或shell脚本中linux终端打印命令有echo和printf. echo命令 功能说明:显示文字.语 法:echo [-ne][ ...
- perl语言与算法的关系
Perl语言是一种高级动态编程语言,它是一种通用的脚本语言,常用于Web开发.系统管理.网络编程等领域.Perl语言由Larry Wall于1987年开发,它的设计理念是"简单.实用.灵活. ...
- 单片机c语言存数据,单片机中C语言的数据存储与程序编写
一.五大内存分区 内存分成5个区,它们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 1.栈区(stack):FIFO就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区. ...
- c语言 两条线段位置,C++/STL实现判断平面内两条线段的位置关系代码示例
概念 平面内两条线段位置关系的判定在很多领域都有着广泛的应用,比如游戏.CAD.图形处理等,而两线段交点的求解又是该算法中重要的一环.本文将尽可能用通俗的语言详细的描述一种主流且性能较高的判定算法. ...
- 按字母位置关系给数字排序(洛谷P4414题题解,Java语言描述)
题目要求 P4414题目链接 分析 这题其实就是排序,特别水,因为只有三个数-- 问题是这排序咋排呢?也不是那么直接的,因为是按照ABC之间位置关系排一下. 其实简单处理的话就是先排序,直接按照ABC ...
最新文章
- web架构之mysql服务器
- Laravel php artisan optimize 源码解读
- 【PC工具】虚拟串口工具Configure Virtual Serial Port Driver6.9汉化版
- sqlserver date转nvarchar_数据库干货:整理SQLServer非常实用的脚本
- 对synchronized的一点理解
- XCTF-MISC-新手区:stegano
- 大三了,计算机专业学生的困惑。 [转]
- 德国80%的统计学教授都会答错的6个与P值有关的问题!
- innerHTML、innerText和outerHTML的区别
- 使程序在后台运行,后台进程实现原理
- 购物直播APP开发系统方案
- linux 命令两个冒号,为什么两个冒号的错误消息作为bash中的命令(::)有三个冒号,但是一个冒号没有输出?...
- dlclose隐藏的秘密!
- 竟有比双十一更令人发指的福利……
- 用python画微笑脸表情_python画表情包
- fdm3d打印机有哪些? Stratasys多品类fdm3d打印机推荐
- 什么是大数据?大数据的特征有哪些?
- upload-labs安装及攻略
- 使用simhash进行海量文章数据相似度去重
- 妖怪正传服务器维护,妖怪正传应用描述查询|妖怪正传应用截图查询|妖怪正传应用包信息|妖怪正传版本记录查询...
热门文章
- mac升级后虚拟机无法启动_使用了自家M1处理器后,苹果新一代Mac迎来三大重点升级...
- Linux下为什么ls直接就可以运行,而你的程序要写./dir1/dir2/bin/bwa才可以
- 23日晚西湖大学鞠峰报告:环境微生物宏基因组学
- MIMOSA2: 基于微生物组和代谢组数据的整合分析
- COM:追踪植物-微生物组互作的进化历史
- pandas使用rename函数自定义重命名dataframe指定索引标签(位置)的名称(customize rename index value or label)
- pandas使用query函数基于dataframe字符串数据列中字符串的长度筛选dataframe的数据行(specific column string length)
- R语言ggplot2包和ggtext包在可视化图像中的指定位置添加文本框(横向文本框、竖向文本框)
- R语言使用pwr包的pwr.f2.test函数对线性回归模型(Linear models)进行效用分析(power analysis)的语法
- R语言dplyr包使用bind_rows函数纵向合并两个dataframe(行生长)、使用bind_cols函数横向合并两个dataframe(列生长)