char** 和const char** 问题

目录

1、char** 和const char** 问题:

2、NUL和NULL问题:

3、sizeof返回值问题:

4、malloc下的strlen问题:


1、char** 和const char** 问题:

今天看书看到一个很有意思的问题,不过在看问题之前,首先得知道一个知识:

我们将实参传递给形参的过程,实际上就是将实参的值赋予给形参的过程。所以如果两个类型之间可以互相赋值没有警告,那么这两个类型就可以作为形参和实参。

这个问题从一个程序开始:

程序1:

void func(const char** p2)
{
    ;
}

int main()
{
	char a = 'a';
	char* pa = &a;
	char** p1=&pa;
	func(p1);
	return 0;
}

      这个问题其实是要我们判断形参实参是否对应,按上面的预备知识,就是转换为判断“ const char** ”、“char**”这两个类型的数据能不能互相赋值。当时我看到这个程序,我第一感觉就是这个程序是有问题的,两个指针类型不相符嘛,一个有const一个没有const,形参实参不对应嘛,很简单。但是当我跑了一下下面这个程序,竟然跑过了,我就感觉很诧异。之前我一直认为只要两个类型不同,就不能赋值。

程序2:

void func(const char* p2)
{
	;
}

int main()
{
	char a = 'a';
	char* pa = &a;
	func(pa);
	return 0;
}

于是我看回书上对于指针类型对象赋值的解释:

要想赋值合法,必须要满足:

两个操作数都是指向有限定符或者无限定符的相容类型的指针。左边的指针(被赋值)所指向的类型必须具有右边指针所指向类型的全部限定符。

      这里的限定符就是const,看完书上的解释,我再看回程序2,char*和const char*分别是指向无限定符和有限定符的char类型指针,不过它们所指向的都是char类型的变量,char类型不是一个指针变量,char类型和和const char 类型是相容的。那为什么说const char * 的指针类型所指向的内容是const char 类型呢?我们来看看下面的一段解释:

const (类型) *  ---- 本身并不是一个有限定符的类型,它的类型是一个“指向具有const限定符的对应类型的指针”,const 修饰的不是指针,而是指针指向的值。

      这里还有一点值得注意,那就是一个指针变量来说,有const和没有const是两个不同的指针类型。再让我们看会为什么char *和const char *是赋值合法的。因为首先它们指向的数据类型分别是是char和有限定符的char类型,这两种数据类型是相容的,并且左边的指针所指向的类型有右边指针所指向类型的全部限定符(左边有const,右边没有)。满足了可以赋值的合法条件。所以它们是合法的。

      这里我们看回程序1:因为程序1中const char ** 所指向的数据类型是“ 有const限定符修饰的char类型的指针” 类型;而char** 所指向的数据类型是 “  没有const限定符修饰的char类型的指针 ”类型。所以两个指针类型是不同的!所以它们是不相容的。故它们的赋值不合法。

2、NUL和NULL问题:

      我们熟知NULL代表的是空指针,即一个不指向任何位置的指针,那么NUL代表什么呢?其实NUL代表的是:字符串的结尾的\0的位模式。

3、sizeof返回值问题:

首先我们来看一个程序:

int main()
{
	int a = -1;
	if (a > sizeof(int))
		printf("hello\n");
	return 0;
}

      上面的程序会输出吗?乍一看,当然不会,int类型大小是4,4当然大于-1,怎么可能会有输出,但是程序一运行,傻眼了,竟然输出了。那究竟是为什么呢?

      其实sizeof的默认返回值是一个无符号的int类型变量,但是这个无符号的类型变量与一个有符号的类型变量a比较时,a会自动算术转换位无符号整型。而-1要是发生无符号整型转换,那将是一个非常大的数字!

4、malloc下的strlen问题:

对于我们用malloc开辟一个字符串,我们要注意不能写成:

malloc(strlen(str));

因为字符串是要有“\0”作为结尾的!!所以要改为 :

malloc(strlen(str)+1);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值