从反思谈论阵列和指针的几个问题,腾讯的笔名

时间:2014.04.18
位置:基地地板
----------------------------------------------------------------------------------------

一、题目

#include<iostream>
using namespace std;
int A(char a[10]) 
{ 
	return sizeof(a); 
}
int main(){
	char a[10]; 
	int result = sizeof(a)* 10 + A(a) * 2;
	cout << result << endl;
	return EXIT_SUCCESS;
}

给出打印结果 ?

----------------------------------------------------------------------------------------

二、数组名与指针

关于数组名关于数组名要明白这么几点 :
1.数组名不是指针数组名的实质是在于它是指代的实体是一种数据结构。这样的数据结构就是数组。

所以:
int a[10];
cout<<sizeof(a);
结果将会是40。由于在这里a指代的是int型的数组。该数组大小为10

2.数组名的外延
正如上面所说,数组名本质上是指代一种数据结构,但它的外延是数组名能够转化为指向其指代实体的指针,并且是一个指针常量,既然这个指针是一个常量的话就不能够对它进行改动和更新操作,比方:
int a[10];
a++;

这样子编译是通只是的。


3.指向数组的指针是第二种变量类型。大小为4byte,只意味着数组的存放地址。由于在函数中,我们经常使用到指向数组的指针。


4.数组名在非常多用途下行为类似指针

比方strcpy函数原型是接受两个參数均为char型指针,但在调用时我们能够传给它两个数组名,所以在这里数组名行为类似指针。


5.数组名的去数据结构内涵
数组名去内涵表现为两点:一是数组名作为函数形參时,在函数体内,会失去它本身的数组数据结构这样的内涵,在函数体内它只表现为一个指针,二是并且,在失去它内涵的同一时候,也失去了常量特性,在函数体内它作为一个普通指针,可增可减可改动。


----------------------------------------------------------------------------------------

三、答案解析

有了这种背景后,我们再来看那个笔试题
#include<iostream>
using namespace std;
int A(char a[10]) 
{ 
return sizeof(a); 
}
int main(){
char a[10]; 
int result = sizeof(a)* 10 + A(a) * 2;
cout << result << endl;
return EXIT_SUCCESS;
}


sizeof(a)  即对数组a求大小,为10
A(a)是将数组名作为函数实參,它的身份沦为普通指针,此时sizeof(a) 为 4
所以输出结果为 108
----------------------------------------------------------------------------------------

四、在来一个腾讯笔试题

#include<iostream>
using namespace std;
void f(char** p)
{
	*p += 2;
}
int main(){
	char* a[] = { "123", "abc", "456" }, **p;
	p = a;
	f(p);
	cout << (**p) << endl;
	return EXIT_SUCCESS;
}


解析:首先定义了一个数组a,该数组a里面存的是char* ,即a[0]是一个指向“123”的指针,a[1]是一个指向“abc"的指针....
然后p是一个指向 指针类型的指针。我们将数组a的首地址即数组地址赋给了p,由于p指向了该数组,当然我们知道p 是指向 指针类型的指针。*p便是指向相应数据类型的指针了,*p指向的char类型,于是*p+=2即向后滑动了2个byte。指向数组a[0][2]处了,***p即字符3,在此处将被打印出来。


----------------------------------------------------------------------------------------

五、还来一道腾讯笔试题

int main(){
	char p1[] = "Tencent";
	void* p2 = malloc(10);
	cout << sizeof(p1) << " " << sizeof(p2) << endl;
	return EXIT_SUCCESS;
}


解析:此处p1是数组名。sizeof(p1)计算的是数组大小,为8byte(加上了一个空字符表示结尾)。sizeof(p2),p2是一个指针,大小为4byte
----------------------------------------------------------------------------------------

六、还再来一个腾讯笔试题

#include<stdio.h>
char* getMem(void)
{
	char* p = "Hello World";
	p[5] = 0x0;
	return p;
}
void test(void)
{
	char* s = 0x0;
	s = getMem();
	printf("The output is: %s",s);
}
int main()
{
	test();
	return 0;
}

解析:s是个char* 型指针,初始化为0x0,即一開始是指向这片地址,后面调用了一个getMen函数,指向一片新地址,这片地址中存了“Hello World",而且在使用s打印字串之前,我们对字串进行过改动,将它中间的空格去换成了结束符’\0‘,这样在用printf按字符串打印时打印到Hello完毕碰到结束字符时它就不再打印了。

注意:上面的解析事实上是我的想当然,题目是原题,也不晓得是怎么回事。是有益的呢还是不有益的呢?但当我亲自调试时出现了断错误。究其原因,一方面是自己基础还不到位。人家略微一糊弄下就掉入陷阱了。在getMen函数中,char*p ="hello wordl"; 这一句仅仅是声明了一个指针变量p,它指向字串”hello world“。而”hello world"他是一个常量字符串。未在程序中使用new要么malloc排序的给它在堆上分配的空间,因此,编译器会为其分配恒定区,在一个字符串常量区值它不同意改变,因此,在程序执行过程中发生断裂错误。










posted @ 2015-12-10 10:47  hrhguanli  阅读(235)  评论(0编辑  收藏  举报