`

字符串指针和字符数组,静态全局、静态局部、全局和局部变量区别,字符串常量和字符串变量,程序的内存分配

 
阅读更多
最近工作之余,发现了两个自己在C语言学习中的难点,一个是字符串指针和字符数组的区别,一个就是静态全局变量、静态局部变量、全局变量和局部变量的区别,在网上查了不少资料,收获良多,现在与大家分享,有错误的地方请大家指正! 
以下程序用VC++6.0调试 
先说说字符串指针和字符数组的区别 1. 相同点: 
/*  用字符数组实现字符串操作 */ main( )  {  
char str[]="Welcome to study C !";    int i; 
printf("%s\n",str);    for (i=0;i<=7;i++)         
printf("%c",str[i]);  //用*(str+i)也行  printf("\n");  }  
 
/*  用字符指针实现字符串操作  */ main()  { 
char *str="Welcome to study C !"; int i; 
printf("%s\n",str);   for(i=0;i<=7;i++)   
printf("%c",*(str+i)); //用str[i]也行 printf("\n"); } 
 
2. 不同点: 
a) 赋值方式不同,字符数组只能对各个元素分别赋值,而字符指针只需赋给字符串的
首地址就可以了。 如:  char *str; 
        str="Welcome to study C !"; 
以下对字符数组的赋值是错误的: 
        char str[80]; 
        str[ ]="Welcome to study C !"; 
b) 字符指针指向字符串,"hello"是一个字符串常量,与之相关联的内存空间位于内
存的只读部分,如: 
  char ch[] = "china\n";   char *p;   char *pp = "CHINA\n";   p = ch;   *(p+2) = 'h';//就是可以的   *(pp+2) = 'h';//此处在编译时不会出错,在执行的时候会出错 






 
c)   函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型,
对于void func (char sa[100],int ia[20],char *p),则sa的类型为char*,而不是char[100]类型  
下面介绍一下字符串常量和字符串变量:  
1.  字符串常量: 
a) 定义:是一对双引号括起来的字符序列 
b) 字符串包含的字符个数:不包括系统自动赋的’\0’,转义字符算1个 c) 所占的字节数:字符串所包含的字符个数加1 
d) 长度:从第一个字符到第一个’\0’之间的字符个数,哪怕’\0’就在原字符串中 e) 无论字符串常量还是字符串变量,空字符串可以存在””,而空字符是错误的’’ 2.  字符串变量: 
a) C语言本身没有设置一种类型来定义字符串变量,字符串的存储完全依赖于字符数
组,但字符数组又不等于是字符串变量,例如: Char str[] = {‘a’,’b’,’c’,’\0’};是str[4],是字符串 Char str[] = {‘a’,’b’,’c’};是str[3],是字符数组 Char str[7] = “string!”;可能破坏其他数据 
b) 在scanf,printf,gets,puts中的str不用写成str[10],只能写成str  
下面介绍下静态全局变量,静态局部变量,全局变量,局部变量的区别    
1. 从作用域看:全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作
用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用 extern 关键字再次声明这个全局变量。 
2. 静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行
结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。 
3. 静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,
它作用于定义它的文件里,不能作用到其它文件里,即被 static 关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。 4. 从分配内存空间看:全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,
而局部变量在栈里分配空间。(扩展内存分配) 
5. 把局部变量改变为静态变量后是改变了它的存储方式即增加了它的生存期。把全局变量
改变为静态变量后是改变了它的作用域,限制了它的使用范围。  
程序的内存分配  
1. 程序占用的内存分为以下几个部分 
a) 栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈。 b) 堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS
回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。 






 
c) 全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的
全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放。 
d) 文字常量区:常量字符串就是放在这里的。 程序结束后由系统释放 e) 程序代码区:存放函数体的二进制代码。 2. 例子程序   
//main.cpp   
int a = 0; 全局初始化区   char *p1; 全局未初始化区   main()   {   
int b; 栈   
char s[] = "abc"; 栈   char *p2; 栈   
char *p3 = "123456"; 123456\0在常量区,p3在栈上。   static int c =0; 全局(静态)初始化区   p1 = (char *)malloc(10);   p2 = (char *)malloc(20);   
分配得来得10和20字节的区域就在堆区。   
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456" 优化成一个地方。   }   因此 static 这个说明符在不同的地方所起的作用是不同的。 若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;  
若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;   
设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;  
如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用 static 变量(这样的函数被称为:带“内部存储器”功能的的函数)    
函数中必须要使用static 变量情况:比如当某函数的返回值为指针类型时,则必须是static 的局部变量的地址作为返回值,若为auto类型,则返回为错指针。  
static 全局变量:改变作用范围,不改变存储位置;static 局部变量:改变存储位置,不改变作用范围;静态函数 :在函数的返回类型前加上static 关键字,函数即被定义为静态函数,只能在声明它的文件当中可见,不能被其它文件使用。 初始化 
如果括号中提供的处置个数大于数组长度,则会出错。如果初值小于数组长度,则将字符赋值给数组中前面的对应元素,其余元素自动填充空字符‘\0’。 
格式化输出字符串时,输出项是字符数组名,不能写成数组中的元素。 输入函数的输入项直接写数组名,不写地址符&。 输入函数遇到空格认为结束。 两个字符数组变量不能直接赋值,只能通过移动下标操作字符数组中的每个元素进行分别赋值;两个字符值指针,可以直接赋值,即把一个字符指针所指向的地址赋值给另一个指针,






 
则两个指针指向的同一个地址。字符数组和字符串两者之间不能直接赋值。    
严格的说两个表达的意思是不完全一样的,因为前者是个字符串指针,这个指针S1所存的地址就是存储字符串前8个字节即hello/n/n/n的那个地址。 而后者是字符数组。每个字符都有一个独立的地址。 见图示。 
字符串变量:在c中是没有这个概念的,c中如果想将一个字符串存放到变量中,必须使用字符数组,就是用一个字符型数组存放一个字符串,一些自己的保护代码,通过软件手段将这段内存软保护起来。这种保护在汇编级别可以轻松突破,其保护也就无效了。 
转自http://wenku.baidu.com/view/448352f9910ef12d2af9e70c.html
分享到:
评论

相关推荐

    谭浩强C程序设计第三版

    字符串常量 48 变量赋初值 48 各类数值型数据之间的混合运算 49 算术运算符和算术表达式 51 C运算符简介 51 算术运算符和算术表达式 51 赋值运算符和赋值表达式 53 逗号运算符和逗号表达式 55 小结 55 C的数据类型 ...

    C语言程序设计(谭浩强)第三版

     8.4.3使用字符指针变量和字符数组的比较  8.5指向函数的指针  8.5.1什么是函数指针  8.5.2用函数指针变量调用函数  8.5.3怎样定义和使用指向函数的指针变量  8.5.4用指向函数的指针作函数参数  8.6返回指针...

    C语言程序设计标准教程

     本程序中用赋值语句给num和name两个成员赋值,name是一个字符串指针变量。用scanf函数动态地输入sex和score成员值,然后把boy1的所有成员的值整体赋予boy2。最后分别输出boy2 的各个成员值。本例表示了结构变量的...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar )

    3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术运算符和算术表达式 45 3.9 赋值运算符和赋值...

    《C语言程序设计》谭浩强

    3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术运算符和算术表达式 45 3.9 赋值运算符和赋值...

    谭浩强c语言程序设计

    3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术运算符和算术表达式 45 3.9 赋值运算符和赋值...

    谭浩强版c语言程序设计

    3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术运算符和算术表达式 45 3.9 赋值运算符和赋值...

    谭浩强 C语言程序设计 教程全书 Word版

    3.5.5 字符串常量 11 3.5.6 符号常量 12 3.6 变量赋初值 12 3.7 各类数值型数据之间的混合运算 13 3.8 算术运算符和算术表达式 14 3.8.1 C运算符简介 14 3.8.2 算术运算符和算术表达式 15 3.9 赋值运算符和赋值...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar

    3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术运算符和算术表达式 45 3.9 赋值运算符和赋值...

    C程序设计 第四版 谭浩强 高清扫描版 带完整书签目录 加 学习辅导

    8.4.3 使用字符指针变量和字符数组的比较 8.5 指向函数的指针 8.5.1 什么是函数指针 8.5.2 用函数指针变量调用函数 8.5.3 怎样定义和使用指向函数的指针变量 8.5.4 用指向函数的指针作函数参数 8.6 返回指针值的函数...

    c语言程序设计(第三版)

    3.5.5 字符串常量 11 3.5.6 符号常量 12 3.6 变量赋初值 12 3.7 各类数值型数据之间的混合运算 13 3.8 算术运算符和算术表达式 14 3.8.1 C运算符简介 14 3.8.2 算术运算符和算术表达式 15 3.9 赋值运算符和赋值...

    谭浩强c语言word版

    3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术运算符和算术表达式 45 3.9 赋值运算符和赋值...

    关于堆栈、静态、动态内存的理解

    全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量、未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 文字常量区 —...

    程序的内存分配

    3、全局区(静态区)(static)―,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 4、文字...

    静态区、堆、栈 区别

    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放。 4、...

    C语言程序设计(PDF格式)

    2.5.2 字符串常量 19 2.5.3 转义字符 20 2.5.4 符号常量 20 2.5.5 字符变量 21 2.6 运算符 22 2.6.1 算术运算符 22 2.6.2 自增和自减 22 2.6.3 关系和逻辑运算符 23 2.6.4 位操作符 24 2.6.5 ?操作符 26 2.6.6 逗号...

    C语言程序设计(高清PDF)

    2.5.2 字符串常量 19 2.5.3 转义字符 20 2.5.4 符号常量 20 2.5.5 字符变量 21 2.6 运算符 22 2.6.1 算术运算符 22 2.6.2 自增和自减 22 2.6.3 关系和逻辑运算符 23 2.6.4 位操作符 24 2.6.5 ?操作符 26 2.6.6 逗号...

    C++各变量的区别

    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放。 4、...

    预备知识―程序的内存分配

    一、预备知识―程序的内存分配 一个由 c/C++编译的程序占用的内存分为以下几个部分 ...4、文字常量区 ―常量字符串就是放在这里的。 程序结束后由系统释放 5、程序代码区―存放函数体的二进制代码。 二、例子程序

Global site tag (gtag.js) - Google Analytics