char*,char a[ ],char*a[]学习、sizeof、位与字节

1 数组的本质
数组是多个元素的集合,在内存中分布在地址相连的单元中,可通过下标访问不同单元的元素。
2 指针的本质
指针也是一种变量,它的内存单元保存的是一个标识其它位置的地址。
printf(“%p”,s);
表示s单元中所保存的地址。
printf(“%p”,&s);
表示s变量本身所在内存单元的地址。
3 指针的指向
指向的直接意思就是指针变量所保存的其它的地址单元中所存放的数据类型。

int * p ;//p 变量保存的地址所在内存单元中的数据类型为整型             
float *q;// ........................................浮点型

不论指向数据类型为哪种,指针变量本身为整型,因为它保存的是地址。
4 字符数组
本质为数组中的元素是字符
str=&str[0];
C语言中操作字符串是通过它在内存中的存储单元的首地址进行的,这是字符串的终极本质。。。
5 char*与char a[]

   char  a [ ] = "hello";
    char *s =a;

    for(int i= 0; i < strlen(a) ; i++)

         printf("%c", s[i]);

     或  printf("%c",*s++);

char*与char a[]的本质区别:
char a[10]——编译器会给数组分配十个单元,每个单元的数据类型为字符。。。
char*p,这是个指针变量,只占4个字节,32位,用来保存一个地址。。。
char *s1=”hello”;
char s2[]=”hello”;
char *s1的s1,指针指向一块内存区域,内存区域大小可以随时改变,而指针指向的常量字符串内容不可以改变。
char s2[]的s2是数组对应着一块内存区域,其地址和容量在生命期内不会改变,数组的内容可以改变。
【内存模型】
+—–+ +—+—+—+—+—+—+
s1: | *======> | h | e | l | l | o |\0 |
+—–+ +—+—+—+—+—+—+
+—+—+—+—+—+—+
s2: | h | e | l | l | o |\0 |
+—+—+—+—+—+—+

场景一)
char *s1 = “hello”;
char s2[] = “hello”;
s2=s1; //编译ERROR
s1=s2; //OK

分析:s2其地址和容量在生命期里不能改变
首先附上阿里在线笔试的一道题目:

对于下面的代码,说法正确的是__

char* s1 = “Hello world”;
char s2[] = “Hello world”;
s1[2] = ‘E’; // 1
s2[2] = ‘E’; // 2
*(s1 + 2) = ‘E’; // 3
*(s2 + 2) = ‘E’; // 4
· 语句2、4是非法的
· 语句3、4是非法的
· 语句1、3是非法的
· 仅语句1是非法的
· 仅语句2是非法的
· 语句1~4都是合法的

上面的题我们选择第三项。
下面我们来详细分析一下。首先这两者有很大区别。
char *s1=”Hello world”这个是一个字符串常量,你可以像一个字符数组一样使用它,但是你不能更改这个字符串的值,比如 s1[2]=’E’这样不合法。
char s2[]=”Hello world”;是一个字符串变量,可以被修改,s2 是函数的栈空间区域,函数执行完成,这个空间就没了。
然而,这两者在作函数的形参的时候是完全等价的。
void function(char *s1);
void function(char s1[]);
可以相当绝对的说这两种完全等价,没有任何区别。

6 字节 sizeof()
字节
位(Bit):0或1
字节(Byte):计算机信息计量单位,1字节=8位;
C++中,int等类型数据所占字节和机器字长及编译器有关系:
32位编译器
char:1字节
char*(即指针变量):4字节(32Bit=4字节)
int:4字节
double:8字节

64位编译器
char:1字节
char*(即指针变量):8个字节(64Bit=8字节)
int:4字节
double:8字节
char a[]="123456789";
sizeof(a)=10;
strlen(a)=9;

sizeof(a)包括了‘\0’,strlen(a)不包括‘\0’。

sizeof和strlen区别:

  1. sizeof是运算符,语言支持的,strlen是个库函数。
  2. strlen求字符串的长度,sizeof求占用的字节数,sizeof包含null字符。
    int a[10];sizeof(a)=4*10=40;
    int *p;sizeof(p)=4
    NULL用来表示空指针常量,可以用p=NULL;来使p成为一个空指针。

7 char *a[]
char *a:
根据优先级,a[]为数组,数组中的元素为char*,char*是一个变量,保存的地址。
char *a[]={“China”,”French”,”America”,”German”};
字符串的本质是地址,a数组中的元素为char*指针,1指针=4字节,4个指针元素=16字节。
4个指针元素代表了4个字符串的首地址,而不是4个字符串本身。
注意:这四个地址是非连续的,它是编译器为”China”,”French”,”America”,”German” 分配的内存空间的地址,所以,4个地址没有关联。

 #include <stdio.h>

   int main()
   {
   char *a [ ] = {"China","French","America","German"};

     printf("%p %p %p %p\n",a[0],a[1],a[2],a[3]); //数组元素中保存的地址
   printf("%p %p %p %p\n",&a[0],&a[1],&a[2],&a[3]);//数组元素单元本身的地址

   return 0;
   }

这里写图片描述
每个地址相差4个字节,这是由于每个元素是1个指针变量占4个字节。
char *s[10] 与char (*s)[10]有区别吗?
区别来源:*优先级<() 和[]的优先级。
char*s[10]表示一个有10个元素的数组,数组的元素类型是char*。
char(*s)[10]表示一个指针,指针指向的是有10个元素的字符数组。
深入 char * ,char ** ,char a[ ] ,char *a[] 内核
char *s 和 char s[] 的区别小结
char *s1和char s2[]的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值