`

赋值操作符的思考

 
阅读更多

         我要说的是一个小问题,感觉写在博客里面比较好。以后看到了可以回忆警示一下。

    问题是这样的:在Java中数组之间能不能通过数组名直接赋值,为什么?

                             在C中数组之间能不能通过数组名直接赋值,为什么

我们先来分析C语言中的情况:

        char arr[3]={'a','b','c'};
	char arrB[3]=arr;    //错的。
	int intArr[3]={1,2,3};
	int intArr2[3]=intArr;   //错的。

      原因很简单,在C语言中数组名相当于一个引用(C++中的引用),由于数组名不是一个变量,所以是不能作为赋值操作符的左值的。举个极端的例子,就像1++;和1=2;肯定是非法的一样(至于深层次的原因,可能是因为C语言为了安全性所做的规定)。

 

但是注意了在C语言中,以下却是可以的:

        char *p="hello";
	char *pB=p;
	printf("%s\n",pB);
//输出结果:
hello

      原因也很简单,“hello”在常量区,p指针保存一个地址指向了"hello"。将p的值赋值给pB也仅仅就是将这个字符串地址的值赋值给了pB。pB是一个指针变量可以作为赋值操作符的左值,所以他接受到了“hello”的地址。

     所以,此时的内存布局是:p和pB两个指针所存储的值是一样的,都是“hello”在常量区的地址。也就是常说的p和pB指向了同一块内存。

 

下来看一下Java环境下的分析:

public class Son{
	public static void main(String args[]){
		int arr[]={1,2,3};
		int arrB[]=arr;
		arrB[0]=5;
		System.out.println(Arrays.toString(arr));
	}
}
//运行结果:
[5, 2, 3]

     可见在Java环境中,采用数组名实现数组之间的赋值是可行的。原因也很简单,在Java中都是值传递,Java中的引用相当于C中的指针。所以arr和arrB是指向了同一块堆。是不是和上面那个C的例子很相像。

 

     最后说一下,在C中结构体是可以通过结构体名相互赋值的:

typedef struct Node{
	int value;
}node;
int main()
{
	node node1={3};
	node node2=node1;
	printf("%d\n",node2.value);

	node2.value=8;
	printf("%d\n",node1.value);
	
	system("pause");
	return 0;
}
//输出结果:
3
3

    我们发现结果竟然不是3和8,所以结构体通过结构体名进行赋值就是简单的值传递的。node1和node2在堆内存中开辟了两个空间,各自是独立的。仅仅是将node1的成员的值赋值给了node2相应的成员。

 

     最后看一个我经常容易忽视的问题:

        char *p="hello";
	char *pB=p
	pB[1]='a';
	printf("%s\n",pB);

 猜猜上面会输出什么?

 答案:发生中断,报错。

原因分析:“hello”是在常量区呀,p只是个指针,并没有给p分配用于存储“hello”的空间,所以p和pB同时指向了常量区的"hello"。常量区是不能修改的。所以报错。

 

解决办法:

        char *p=(char*)malloc(sizeof("hello"));
	memcpy(p,"hello",sizeof("hello"));
	char *pB=p;

	pB[2]='a';
	printf("%s\n",p);
	printf("%s\n",pB);

 此时,p拥有了自己的存储"hello"的内存空间(在堆区),但是pB没有。pB仅仅就是指向了p的那块内存。所以可以说pB就是个穷指针。

分享到:
评论

相关推荐

    像计算机科学家一样思考Python(第2版).pdf

    5.1 向下取整除法操作符和求模操作符 41 5.2 布尔表达式 42 5.3 逻辑操作符 42 5.4 条件执行 43 5.5 选择执行 43 5.6 条件链 44 5.7 嵌套条件 44 5.8 递归 45 5.9 递归函数的栈图 46 5.10 无限...

    Absolute C++中文版(原书第2版)-完美的C++教程,文档中还包含英文版

    14.2.1 派生类中的赋值操作符和复制 构造函数 426 14.2.2 派生类的析构函数 426 14.2.3 保护继承和私有继承 436 14.2.4 多继承 437 第15章 多态与虚函数 442 15.1 虚函数基础 442 15.1.1 后绑定 442 15.1.2 ...

    java 编程入门思考

    5.2 Java访问指示符 5.2.1 “友好的” 5.2.2 public:接口访问 5.2.3 private:不能接触 5.2.4 protected:“友好的一种” 5.3 接口与实现 5.4 类访问 5.5 总结 5.6 练习 第6章 类再生 6.1 合成的语法 6.2 继承的...

    perl语言脚本文档说明

    2.4.4 其他赋值运算符 22 2.4.5 关于字符串和数字的一些说明 22 2.5 练习:利息计算程序 23 2.6 课时小结 24 2.7 课外作业 24 2.7.1 专家答疑 24 2.7.2 思考题 24 2.7.3 解答 25 2.7.4 实习 25 第3学时 ...

    24日学好Perl语言

    2.4.4 其他赋值运算符 22 2.4.5 关于字符串和数字的一些说明 22 2.5 练习:利息计算程序 23 2.6 课时小结 24 2.7 课外作业 24 2.7.1 专家答疑 24 2.7.2 思考题 24 2.7.3 解答 25 2.7.4 实习 25 第3学时 控制程序流 ...

    perl学习文档

    2.4.4 其他赋值运算符 22 2.4.5 关于字符串和数字的一些说明 22 2.5 练习:利息计算程序 23 2.6 课时小结 24 2.7 课外作业 24 2.7.1 专家答疑 24 2.7.2 思考题 24 2.7.3 解答 25 2.7.4 实习 25 第3学时 控制程序流 ...

    PERL编程24学时教程.pdf

    2.4.4 其他赋值运算符 22 2.4.5 关于字符串和数字的一些说明 22 2.5 练习:利息计算程序 23 2.6 课时小结 24 2.7 课外作业 24 2.7.1 专家答疑 24 2.7.2 思考题 24 2.7.3 解答 25 2.7.4 实习 25 第3学时 控制程序流 ...

    Perl编程24学时教程(PDF格式,共24章)

    2.4.4 其他赋值运算符 22 2.4.5 关于字符串和数字的一些说明 22 2.5 练习:利息计算程序 23 2.6 课时小结 24 2.7 课外作业 24 2.7.1 专家答疑 24 2.7.2 思考题 24 2.7.3 解答 25 2.7.4 实习 25 第3学时 控制程序流 ...

    PERL编程24学时教程

    2.4.4 其他赋值运算符 22 2.4.5 关于字符串和数字的一些说明 22 2.5 练习:利息计算程序 23 2.6 课时小结 24 2.7 课外作业 24 2.7.1 专家答疑 24 2.7.2 思考题 24 2.7.3 解答 25 2.7.4 实习 25 第3学时 控制程序流 ...

    perl编程24学时教程.rar

    2.4.4 其他赋值运算符 22 2.4.5 关于字符串和数字的一些说明 22 2.5 练习:利息计算程序 23 2.6 课时小结 24 2.7 课外作业 24 2.7.1 专家答疑 24 2.7.2 思考题 24 2.7.3 解答 25 2.7.4 实习 25 第3学时 ...

    传智播客扫地僧视频讲义源码

    15_友元函数实现左移右移操作符重载(函数返回值当左值需返回引用)_传智扫地僧 16_友元函数实现操作符重载知识总结 17_重载等号操作符_传智扫地僧 18_数组类小案例_操作符重载需求 19_数组类小案例_重载[]_传智扫地...

    开学了,有路网团购太便宜啦! C++编程惯用法(高级程序员常用方法和技巧)/深入C++系列(C++ Strategies and Tactics)

    2.5 操作符重载:成员或非成员? 2.6 重载、缺省值以及省略符 2.7 Const 2.8 返回值为引用 2.9 静态对象的构造 2.10 小结 2.11 问题 第3章 句柄 3.1 一个String类 3.2 使用计数器来避免多份拷贝 3.3 避免进行重编译...

    C++大学教程,一本适合初学者的入门教材(part2)

    1.4 操作系统的变革 I.5 个人计算、分布式计算与客户/a匠务器计算 l. 6 机器语言、汇编语言和高级语言 1.7 C语言与C++的历史 1.8 C++标准库 1.9 Java、Internet与万维网 1.10 其他高级语言 1.11 结构化编程 ...

    C++大学教程,一本适合初学者的入门教材(part1)

    1.4 操作系统的变革 I.5 个人计算、分布式计算与客户/a匠务器计算 l. 6 机器语言、汇编语言和高级语言 1.7 C语言与C++的历史 1.8 C++标准库 1.9 Java、Internet与万维网 1.10 其他高级语言 1.11 结构化编程 ...

    Scala程序设计(第2版)

    3.8 条件操作符 71 3.9 使用try、catch和final子句 72 3.10 名字调用和值调用 75 3.11 惰性赋值 78 3.12 枚举 79 3.13 可插入字符串 81 3.14 Trait:Scala语言的接口和“混入” 83 3.15 本章...

    面向对象技术与UML课件及源代码-by 南邮-陈杨

    第11章Java IO操作 第12章多线程开发 第13章反射技术 第14章实验指导3 下篇UML 第15章UML入门 第16章用例图 第17章类图和对象图 第18章实验指导4 第19章顺序图、协作图、状态图和活动图 第20章包图、...

    华为编程开发规范与案例

    5、正确使用逻辑与&&、屏蔽&操作符 第17页 【案例1.5.1】 第17页 6、注意数据类型的匹配 第18页 【案例1.6.1】 第18页 【案例1.6.2】 第18页 7、用于控制条件转移的表达式及取值范围是否书写正确 第20页 【案例1.7.1...

    代码之美(中文完整版).pdf

    9.7. 前置操作符 9.8. 赋值运算符 9.9. 常数 9.10. Scope 9.11. 语句 9.12. 函数 9.13. 数组和对象字面量 9.14. 要做和要思考的事 第 10章 追求加速的种群计数 10.1. 基本方法 10.2. 分治法 10.3. 其他方法 10.4. 两...

Global site tag (gtag.js) - Google Analytics