C语言的 a, *a, &a

1. 存储单元:

存储单元一般应具有存储数据和读写数据的功能,以8位(bit) 二进制作为一个存储单元,也就是一个字节。

一个变量代表了一个存储单元,其中的值是可变的,故称为变量。

变量有三个要素是:变量名、变量类型、变量值。

int a = 10;

变量 a 本质上代表一个存储单元。CPU通过该存储单元的地址访问该存储单元中的数据。

所以a本来代表两个值:存储单元的地址和储单元中的数据。于是就有了二异性。

为了消除这种二义性,C语言规定a表示存储单元中的数据,&a表示存储单元的地址。

2. 操作符 *、&

’*’:取某地址的值(数据内容),运算符后通常跟一个地址

’&’:取某数据(变量)的地址,运算符后通常跟一个变量**

  • ‘a’: 表示a对应的存储单元中的数据。

  • ‘&a’: 表示a对应的存储单元的地址。

  • ‘*a’: 首先,要求 a 对应的存储单元中的数据一定是另一个存储单元的地址。于是,*a表示另一个存储单元中的数据。

int*: 即是指针。

指针类型的大小是固定的(无论该指针指向哪种数据类型),在32位系统中为4字节;在64位系统中为8字节;

3. 指针与字符数组

3.1 字符数组

char str[10] = {"hello world"};

当编译这句代码时,编译器会将str数组中的元素从第一个元素开始逐个填入(hello world\0 )。

C语言中规定 数组名 代表数组所在内存位置的首地址,也是 str[0]的地址,即str = &str[0];

3.2 字符指针

char *s ;
s = "Hello";

为什么可以把一个字符串赋给一个指针变量??这不是类型不一致吗???

C语言中编译器会给字符串常量分配地址,如果 “Hello”, 存储在内存中的 0x3000 0x3001 0x3002 0x3003 0x3004 0x3005 .其实真正的意义是 s =&“H” = 0x3000;

char* s = "hello";
char a[] = {"hello"};
//实质上,s 和 a 的值相同,都是 &'h',数组首地址

3.3 char ** 与char * a[]

char** s = "hello";

s 是一个二级指针,s中储存的值是:存储内容为数组首地址的变量的地址。

char* a[4] = {"China","French","America","German"}
  1. 由于[] 的优先级高于’* '所以a先和 []结合,所以char* a[] 本质是一个数组,数组中的元素是char * 类型的字符指针,
  2. a 数组中的元素是对应字符串首字符的地址。即:a[0] = &‘C’, a[1] = &‘F’ …
  3. 那么sizeof(a) 是多少呢,有人会想到是五个单词的占内存中的全部字节数 6+7+8+7 = 28;但是其实sizeof(a) = 16;因为 a 数组中的元素为char * 指针,指针变量占四个字节(64bit编译器为8个字节),那么四个元素就是16个字节了。
  4. 所以 数组名 a 代表着 储存各个字符串首字符地址的地址数组的第一个元素的地址,即 &a[0] / &(&‘C’)

参考 https://www.jianshu.com/p/fe0d7ac36988

  • 12
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值