2014年3月31日星期一

一道关于指针的Google笔试题

[题目]



const char *p="hello";
foo(&p); //函数foo(const char **pp)

下面说法正确的是[]
A.函数foo()不能改变p指向的字符串内容
B.函数foo()不能使指针p指向malloc生成的地址
C.函数foo()可以使p指向新的字符串常量
D.函数foo()可以把p赋值为 NULL.


简单地说,p是一个字符串。

实际上,p是一个普通的指针(可以修改指向),这个指针指向一个不可改变的字符(i.e. 这个指针本身的值是一个字符在内存中存储的地址),这个字符是常字符串"hello"的第一个字符。

const char **pp是一个指针,这个指针指向一个指针',指针'就是像上述的p那样的指针。函数foo仅接受一个参数,这个参数的值是pp要指向的那个指针自己在内存中的地址(不是那个指针指向的地址),正是由于这个原因,第二句写的是foo(&p),将指针p自己的地址传了进去。此时pp的值就是p的地址,*pp就是p的值,也就是p指向的常字符的地址(或者说常字符串的首地址,因为char*既可以指向字符''又可以指向字符串"",不管指向什么,它都只是存一个字符在内存中的地址,如果指向字符串,那么它存第一个字符的地址,后面的字符是通过指针的加法运算来访问的)。下面依次分析每个选项:
A. 可以通过**pp来读取p指向的字符的值,但是p是指向const char,所以只能读取,不能改变内容,A正确。

B. malloc是从内存中申请空间的函数,它返回申请到的空间的首地址(起始地址)。根据上面的分析,通过为*pp赋值,即可改变p的值,也就是使p的指向。另外,“声明const char* p”的意思不是“p只能指向字符串常量”,而是“不能用p来修改那个字符串”,用普通的char*再指向那个字符串,还是可以修改那个字符串的。换句话说,字符串本身是不带“只读”属性的,是不是只读,在于用户声明的调用方式。例:
    const char s[10]="abcde";
char* p = s;
p[1]='p'; //可行,s[]被修改为"apcde"
s[1] = 'p';//不可行,error: assignment of read-only location 's[1]'

又例:
    const char* p="abcd";
char s[10] = "defg";
p = s;//可以修改指向
p[1] = 'j'; //可以修改s[]为"djfg"

所以foo()能够使p指向malloc生成的地址。B错误。


C. p是指向字符串常量的指针,const修饰的是char,不是char*,所以“只读”的是p指向的那个字符串,而不是p本身。因此,p的指向是可以改变的,可以令它指向其他字符串常量。给*pp赋值即可。C正确。

D. 根据以上分析,可以将p赋值为null(让p指向空)。D正确。

2014年3月13日星期四

你为什么需要一个Windows平板电脑

windows平板电脑比智能手机、ipad好在哪?

屏幕大(与手机相比);

操控方式多,可用笔;

可以运行PC程序。

1.携带和阅读电子资料,如名著、课本、教学视频。包括pdf、常见图片格式、常见视频格式。chm、exe可能也有少量需要。

2.更方便快捷地查阅信息。做作业时查知识点和题目,上课时查疑惑点,还可以方便地查询一些生活信息。

3.书写功能。可以用来记临时信息(笔记)、做草稿纸等。与纸张相比,有媒体承载形式多样(可以插入照片)、环保等优点。

4.比笔记本电脑更便携,哪里都装得下,又能兼容笔记本电脑上的软件。用笔或蓝牙鼠标键盘,可以在上专业课(如程序设计课)时代替笔记本电脑。

5.减少无意义的用笔记本电脑时间,从而减少在网上时间的浪费。

6.可以用专业的乐谱编辑软件来看乐谱。很方便,还能示范演奏。