Chinaunix首页 | 论坛 | 博客
  • 博客访问: 543511
  • 博文数量: 101
  • 博客积分: 1889
  • 博客等级: 上尉
  • 技术积分: 906
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-14 16:22
文章分类

全部博文(101)

文章存档

2012年(11)

2011年(19)

2010年(59)

2009年(12)

我的朋友

分类: C/C++

2010-05-24 11:57:07

字符串  指针 数组

 

一、定义

a、字符串:字符串我常理解为一个带‘\0结束符的串常量,其在内存中是顺序表的形式连续存储在内存的常量区。也可理解为以‘\0结尾的char 数组。

 

 b、数组:    数组作为构造数据类型的一种,其由一系列类型相同的元素组成,在内存中是以顺序表的形式存放。数组主要由两部分组成-----元素类型和元素个数,这个两个元素将决定数组在内存中占据的空间大小,该内存段的开始地址可有数组明标示出,所以数组名为一常量。

例如:char a[10],该例定义的是一个连续存储的10char 类型的内存区域,该内存区域的开始地址由数组名‘a’可得到。

 

c、指针:  指针作为C语言的精髓,其是作为一个存放地址的变量,声明指针时给与的数据类型是指指针所存地址内的数据的类型。

例如:char *P, 该定义是指P指针存放char 类型的变量地址。

二、初始化

a、  字符串:字符串常量的定义是用双引号标记。例如:“abcd,编译器会认为这是一个字符串并在加上\0字符后将其存入静态数据存储区的常量区中。在此特别注明字符串常量“abcd”其实代表了其在内存中的首地址,知道了这一点那么 char *p=abcd,指针赋值方式就不难理解了。

b、  指针: 指针作为存储地址常量的变量,在使用之前一定要进行初始化,不然将带来出乎意料的后果。例如下列程序:

#include

 

int main ()

{

 

     char *p;

     scanf("%c",p);

     printf("%c",*p);

     system("pause");

     return 0;

}

该程序在语法上完全没有错误,但在执行时DEV C++环境下,编译器会提示进程错误。这是为什么呢?这就是指针初始化的问题。

在指针被定义时,其初值是个不确定的随机值。该值可能是内存的只读区地址(根据编译器的不同而不同),这就是进程无法进行的根源。指针一定要初始化!任何指针!切记!

指针的初始化有两种方式:

 1、静态初始化(可能不专业,我自己取的名字)   int i; int *p=&i;

 2、动态初始化,如 int *p;

                   p=(int *)malloc(sizeof(int));            

 

c、  数组:数组的初始化可有两种

1、  定义时初始化 ,即:char a[]={a,b,c}或者用字符串初始化 如:char a[]=”abcd”; 对于数组的初始化需要特别指出,在自动存储类型下,如果你在定义数组时没有给数组元素赋初值,那么数组元素所表示的是个不确定值,例如:

                 Int a[10];

                 Printf(“%d”,a[1]);

   该输出是&a[1] 此前被使用时所存的值。如果数组在定义只初始化了个别元素的值,则其他元素初始化为0;例如:

char p[2]={1};

printf("%d",p[1]);

           该输出为0. 定义式初始化数组时,编译器支持指定初始化,例如:

int a[10]={[9]=1};

           即表示a[9]=1,根据前面一原其则,其它则被初始化为0

       

2、  定义以后初始化,即:

    char a[2];

                      for(int i=0;i<2;i++)

                           a[i]=i;

         在数组定义以外初始化数组必须借助元素下标,例如:a[i]=0;

       在用字符串用如下形式初始化,则必然出错,例如;

                       char a[10];

                       a=”abcd”;

                前面讲数组的定义时已讲到,数组名为一常量,它表示线性表的第一个存储位置的地址,不能对常量赋值。

                可能你会问 为什么 char a[]=”abcd”,又能通过编译呢? 这还得从编译器对此条语句的执行原理说起。在定名上面数组语句时,编译为数组分配内存空间,并从静态存储区中将字符串常量逐一拷贝到此分配的内存区间中。

 

三、数组、指针在对“字符串“操作的区别

       该问题从下列来说明:

     例一:

       #include    
         char   p[]   =   "Hello";  
   
         int   main()  
       {  
          p[0]   =   'X';  
          printf("%s",   p);  
          return   0;  
        }  
    
例二:

        #include    
         char *p   =   "Hello";  
   
        int   main()  
      {  
          p[0]   =   'X';  
           printf("%s",   p);   //p表示数组的起始地址,为什么不用p++
           return   0;  
      }  

 

例子一中,char   p[]   =   "Hello";  语句是数组P[]做了字符串“Hello“的拷贝,所以他可以对拷贝字符串做任意修改。

而例二中, char*   p   =   "Hello"; 字符串常量将自己在静态存储区中的开始地址赋给了p指针,通过p指针操作的静态存储区中的字符串数据源,如果编译器有对静态存储区有保护机制的话,该类操作违法。同时,改变数据源的做法也不可取

阅读(1375) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~