字符数组与字符串指针

字符数组:

char a[]="aaaaa";

存储上:如果是局部变量,那么会在栈中以a作为首地址开辟出6个字符空间即可,自动加上\0这个字符的存储。

字符串:

char *a="aaaaa";

存储上:在常量区分配出包括\0在内的6个字符空间,指针中存储这个地址即可。

所以还要在栈上给这个指针变量开辟出4个字节的存储单元(具体要看平台的大小),

32位处理器上32位操作系统的32位编译器,指针大小4字节。
  32位处理器上32位操作系统的16位编译器,指针大小2字节。  
  32位处理器上16位操作系统的16位编译器,指针大小2字节。
  16位处理器上16位操作系统的16位编译器,指针大小2字节。

这从结果看起来指针的大小和编译器有关??

  实际不是这样的,有这样的结果是因为以上几种情况,处理器当前运行模式的寻址位数是不一样的,如下:

  Intel 32位处理器32位运行模式,逻辑寻址位数32,指针也就是32位,即4个字节
  Intel 32位处理器16位虚拟机运行模式,逻辑寻址位数16,指针也就是16位,即2个字节

  编译器的作用是根据目标硬件(即CPU)的特性将源程序编译为可在该硬件上运行的目标文件。如果一个编译器支持某32位的CPU,那么它就可以将源程序编译为可以在该CPU上运行的目标文件。该源程序中指针大小也会被编译器根据该CPU的寻址位数(如32位)编译选择为4字节。

  综上可得:指针大小是由当前CPU运行模式的寻址位数决定!

但一般是分配int型大小的字节给这个指针变量使用。

赋值过程:

char a[10]; 

a="hello";

   这种情况容易出现,a虽然是指针,但是它已经指向在堆栈中分配的10个字符空间,现在这个情况a又指向数据区中的hello常量,这里的指针a出现混乱,不允许!

但是可以出现:

char *a;

因为这里的a没有指向堆栈中的一块空间。

a="hello";

这里代表个使得指针指向一个地址。

include <stdio.h>

int main()
{
    //字符串常量,存放于内存常量区。
    //常量区区的内存具有缓存机制,
    //当不同指针指向的常量值相同时,
    //其实这些指针指向的是同一块常量区内存
    //且常量区内存不允许被程序修改
    char *str1 = "hello";
    char *str2 = "hello";
修改方式上    
    //报错
//    *(str1+2)='A';
为了防止通过该指针修改指针指向的内容,因为该内容是常量区,不可以被修改
所以,应该变成常量指针:const char *str1="hello"
这样就不可能通过这个指针修改其中的数据
这样:*(str+1)='a'
就是错误的
先看一个例子:

 const修饰函数的参数

       1)防止修改指针指向的内容,如:

(常量指针:防止通过该指针修改指向的数据)

void StringCopy(char *dst, const char *src);

     2)防止修改指针所指向的地址,如:

void swap(int * const p1, int * const p2);

(指针常量:防止通过该指针修改指针指向的地址)
 

    
    printf("str1 = %p\n",str1);
    printf("str2 = %p\n",str2);
    
    
    //字符串变量存放于栈内存中,
    //不同字符数组指向的字符串值相同,
    //也是保存在两块不相同的内存中
    //且栈内存允许被程序修改
    char str3[] = "hello";
    char str4[] = "hello";
    
    //不报错
因为这里的字符串是个变量,所以可以进行修改。
//    str3[2]='A';
    
    printf("str3 = %p\n",str3);
    printf("str4 = %p\n",str4);
    
    return 0;
}

复制代码

结果:

str1 = 0x10f17df80
str2 = 0x10f17df80
str3 = 0x7fff50a82bf2
str4 = 0x7fff50a82bec

#include <stdio.h>
#include <string.h>

int main()
{
    char c1[] ="helloworld";
    char *c2 = "helloworld";

    printf("sizeof(s1) :  %d %d\n", sizeof(c1), sizeof(c2));
    printf("strlen(s2) :  %d %d\n", strlen(c1), strlen(c2));

    return 0;
}

strlen计算字符串的长度,不算这个\0

这段程序运行的结果是:

11 4

10 10
 

例如

char *str = "1111111abcd";

char str1[9] = {1};

sizeof(str)  = 4; //是指指针所占的字节大小,在c/c++中一个指针占4个字节(32位系统)

sizeof(str1) = 9;

sizeof()是运算符,由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。实际上,用sizeof来返回类型以及静态分配的对象、结构或数组的空间,返回值跟这些里面所存储的内容没有关系

猜你喜欢

转载自blog.csdn.net/chengchaonan/article/details/88936338