C语言指针类型重要性

C语言中,带上类型运算是一个很好的习惯。

我们来看一道题目。


若定义 char a[3][3]={ad, ce, fb}, *s = (char *)a; 那么下列表达式语法正确,并且其值与 a[2][1]相等的表达式是_______

  A*(a+3) B*(*a+5) Cs[2][1] D*++s-2


答案是D

这题设计的挺巧妙,其中有个理解的重点: *s = (char *)a

其中s 这个指针指向什么?指向这个整个二维数组吗?肯定不是,不然答案就是C了。

那么试想我们能不能这么定义呢:

*s = a
那么就会报出这样的错误:

cannot convert 'char (*)[3]' to 'char*' in initialization

这个问题我相信大家都明白怎么解决。那么为什么进行强制类型转换就能指向数组的首地址了呢?

我们先来看这样一个问题:

int a, b;
a + b;

我们应该怎么看待a+b?我们应该这样看这个表达式即两个int变量相加,而不应该单单看作两个变量相加。

我通过一个例子来讲解:

int *p,a=1;
    p = &a;
    p++;

这里如何理解p++? 按照上面所说,运算应该带上类型。所以这里应该是p + sizeof(int),即地址加了4

那么如果把p定义成char*型指针呢?如:

char *p;
int a=256;
p = (char*)&a;
printf(“%d\n”, *p);

那么输出的结果是什么呢?

结果是0

printf(“%d\n”, *(p + 1));
如果是上述输出呢?

结果是1

我们来研究一下:int 在内存中存储占4个字节,所以十进制256用二进制表示应该是

00000000 00000000 00000001 00000000

每一个地址代表一个存储单元。所以如果我们用一个指向int的指针来指向a,那么这个指针其实是指向4个字节的,所以指针加一其实是加sizeofint)。现在我们把一个char*型的指针指向被我们强制转换成char*型的a。而char在内存中以单个字节存储。那么虽然p存放的还是a的地址,但是p更精准的应该是指向a的第一个字节的内容。所以*p对应(inta中的第一个字节 即00000000 ,所以输出0*(p + 1)即*(p + sizeof(char)),对应的是(inta中的第二个字节,即00000001,所以输出1.

这样理解上面的(char*)就简单多了。(char*)a将原先指向(char *[3])强制转换成(char *),这样其实是缩小了步长(不知这么比喻是否合适),即原先指向3个字节强制转换成1个字节,那么p就能接纳数组的首地址了。那么*++s实际上指向的是a[0][1],也就是“d”,而“d-2 就是“b”。

所以养成带类型运算的习惯真的很重要。


另外我一直没说数组名是一个指针,因为它确实不是。但这不再讨论范围之内,只是解答为什么我为什么不把数组名说成指针来帮助理解。

最后欢迎指出我的错误。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值