第二次考核问题总结
2017-11-26 18:48
134 查看
上题:int a[][3] = { {1, 2}, {3, 4, 5}, {6, 7, 8}, {9} };问:a[0][2]、a[0][3]、a[1][3]、a[0][8]、a[1][7]的值。
答案:0、3、6、8、0
解析:
首先说a[][3]的意思,后面的3表示数组里最多保存3个数。
a[0][2],0表示是第1个大括号({}),2表示第1个大括号({})里的第3个值。显然,没越界(第1个数组的界),然后第3个值没赋值,同时前两个值赋值了,所以,第1个数组(大括号({}))的第3个值为0。
a[0][3],0还是表示第1个大括号,3表示第1个大括号里的第4个值,越界了(最多只能保存3个值),越界后,就会跑到下一个数组(大括号)里,越了1个,所以,a[0][3]的值就为a[1][0]的值,即3。
a[1][3],1表示第2个大括号,3表示第2个大括号里的第4个值,一样,越界了,所以a[1][3]表示的就是a[2][0]的值,即6。
a[0][8],表示的是第1个大括号的第9个值,前面的值为(1,2,0;3,4,5;6,7),所以第9个值为8,即a[2][3]的值。
a[1][7],表示的是第2个大括号里的第8个值,前面的值为(3,4,5;6,7,8;9),所以第8个值为0,即a[3][1]的值。
所以,可以再总结下:比如二维数组,将其每个项的的最大的数值写出来,像上面那个例子,每个项最大就为a[3][2],前面的项,第一个项,不能越界,第二个项里的,可以越界,越出去的,就又从下一组里的头开始数,最后到了哪个数,就是哪个数。当然,如果把整个数组的值都越完了也是不可以的。
对于数组的整体赋值,只能在首次定义时整体赋值。解释:定义数组时,数组的地址已经确定,并且不可修改,所以,如果在定义完数组后,再整体(比如字符串)赋值给数组,就是要改变数组的地址,这是不允许的。所以,要整体赋值,就尽快,要是等到已经定义完了,就不能再赋值了,因为数组的地址已经确定,就不可再修改了。
例:char arr[20] = "helloworld"; 正确! char arr[20]; arr = "helloworld"; 错误!
char arr[20] = "helloworld"; *(arr+1) = 'w'; 正确!
但对于指针的整体赋值,可以任意时候赋值。解释:定义指针,只是定义了一个字节(32位)保存指针的值,并且,它的值是可以被修改的,指针可以指向任意区域(或字符串)。但,指针相对于数组有个限制,即不能通过指针解引用修改相应内存区域的值,(此原因不确定:一个内存区域可以被多个指针所指向,这个内存是共享的,所以不能某个指针去修改它)
例:char *p = "helloworld"; 正确! char *p; p = "helloworld"; 正确!
char *p = "helloworld"; *(p+1) = 'w'; 错误!
如上,最后打印的值为什么。
在vs2012中,答案肯定不唯一,内存地址是会变的,每次运行,它的地址都不一样。但规律不会变。
首先,a、b[0]、b[1]都是在函数中的变量,局部变量。所以,他们都位于栈中,所以,前面的变量位于后面变量的“下边”(即高地址),对于栈而言,a是一个整体,b这个数组是一个整体,所以,肯定a在b数组的“下边”,所以a的地址高,b数组的地址低,理论情况,a的地址比b数组的地址高sizeof(int)个字节,即4个字节,但在vs2012中,栈中的变量跟变量之间都会安防“两个炸弹”,每个“炸弹”4个字节,安全考虑(全局变量区和动态内存区没有“炸弹”)。所以,a的地址就会比数组b的地址高4+4*2个字节,即12个字节。然后看b[0]和b[1],他俩位于一个数组中,数组中的元素是按顺序分配地址的,对于栈而言,b[0]和b[1]是一个东西,所以,b[0]和b[1]不遵循栈的规则,所以b[1]比b[0]大4个字节。所以,结果肯定遵循这样的规律:&b[0]
+ 4 = &b[1],&b[1] + 12 = &a。
未完待续......
答案:0、3、6、8、0
解析:
首先说a[][3]的意思,后面的3表示数组里最多保存3个数。
a[0][2],0表示是第1个大括号({}),2表示第1个大括号({})里的第3个值。显然,没越界(第1个数组的界),然后第3个值没赋值,同时前两个值赋值了,所以,第1个数组(大括号({}))的第3个值为0。
a[0][3],0还是表示第1个大括号,3表示第1个大括号里的第4个值,越界了(最多只能保存3个值),越界后,就会跑到下一个数组(大括号)里,越了1个,所以,a[0][3]的值就为a[1][0]的值,即3。
a[1][3],1表示第2个大括号,3表示第2个大括号里的第4个值,一样,越界了,所以a[1][3]表示的就是a[2][0]的值,即6。
a[0][8],表示的是第1个大括号的第9个值,前面的值为(1,2,0;3,4,5;6,7),所以第9个值为8,即a[2][3]的值。
a[1][7],表示的是第2个大括号里的第8个值,前面的值为(3,4,5;6,7,8;9),所以第8个值为0,即a[3][1]的值。
所以,可以再总结下:比如二维数组,将其每个项的的最大的数值写出来,像上面那个例子,每个项最大就为a[3][2],前面的项,第一个项,不能越界,第二个项里的,可以越界,越出去的,就又从下一组里的头开始数,最后到了哪个数,就是哪个数。当然,如果把整个数组的值都越完了也是不可以的。
对于数组的整体赋值,只能在首次定义时整体赋值。解释:定义数组时,数组的地址已经确定,并且不可修改,所以,如果在定义完数组后,再整体(比如字符串)赋值给数组,就是要改变数组的地址,这是不允许的。所以,要整体赋值,就尽快,要是等到已经定义完了,就不能再赋值了,因为数组的地址已经确定,就不可再修改了。
例:char arr[20] = "helloworld"; 正确! char arr[20]; arr = "helloworld"; 错误!
char arr[20] = "helloworld"; *(arr+1) = 'w'; 正确!
但对于指针的整体赋值,可以任意时候赋值。解释:定义指针,只是定义了一个字节(32位)保存指针的值,并且,它的值是可以被修改的,指针可以指向任意区域(或字符串)。但,指针相对于数组有个限制,即不能通过指针解引用修改相应内存区域的值,(此原因不确定:一个内存区域可以被多个指针所指向,这个内存是共享的,所以不能某个指针去修改它)
例:char *p = "helloworld"; 正确! char *p; p = "helloworld"; 正确!
char *p = "helloworld"; *(p+1) = 'w'; 错误!
int main() { int a; int b[2]; printf("%x,%x,%x\n", &a, &b[0], &b[1]); return 0; }
如上,最后打印的值为什么。
在vs2012中,答案肯定不唯一,内存地址是会变的,每次运行,它的地址都不一样。但规律不会变。
首先,a、b[0]、b[1]都是在函数中的变量,局部变量。所以,他们都位于栈中,所以,前面的变量位于后面变量的“下边”(即高地址),对于栈而言,a是一个整体,b这个数组是一个整体,所以,肯定a在b数组的“下边”,所以a的地址高,b数组的地址低,理论情况,a的地址比b数组的地址高sizeof(int)个字节,即4个字节,但在vs2012中,栈中的变量跟变量之间都会安防“两个炸弹”,每个“炸弹”4个字节,安全考虑(全局变量区和动态内存区没有“炸弹”)。所以,a的地址就会比数组b的地址高4+4*2个字节,即12个字节。然后看b[0]和b[1],他俩位于一个数组中,数组中的元素是按顺序分配地址的,对于栈而言,b[0]和b[1]是一个东西,所以,b[0]和b[1]不遵循栈的规则,所以b[1]比b[0]大4个字节。所以,结果肯定遵循这样的规律:&b[0]
+ 4 = &b[1],&b[1] + 12 = &a。
未完待续......
相关文章推荐
- 微信支付开发若干问题总结,API搞死人(谢谢ζั͡ޓއއއ๓http://www.thinkphp.cn/code/1620.html)血淋淋的教训,第二次栽这里了
- 关于今天小考核的问题的总结
- 月考核前部分问题总结
- Java技巧库--->java(Web)中相对路径,绝对路径问题总结
- redis总结4-KEY设计技巧,常见问题
- 实践问题总结(一)
- thinkphp整合dwz 和xhEditor遇到的问题总结
- Php防止重复提交问题总结
- ASP.NET安装问题总结
- [总结]redis连接超时问题排查
- Jboss4.2.*版本环境搭建产生问题解决总结
- Oracle 错误总结及问题解决 ORA
- IIS特有问题,网上看了好多都不正确或者不全面,经过试验总结
- python3出现转码问题的总结
- windows server 2008安装wampserver后几种小问题个人总结
- Spring源码编译及过程中的一些问题总结
- Activity之间使用intent传递大量数据带来问题总结
- 【总结】Java与字符编码问题详谈
- 项目问题总结一、全局变量引起的并发问题