原文链接 http://blog.youkuaiyun.com/yuanjilai/article/details/8043784
1、写出程序的输出(2012搜狗校招笔试)
- char *c[] = { "ENTER", "NEW", "POINT", "FIRST" };
- char **cp[] = { c+3, c+2, c+1, c };
- char ***cpp = cp;
- int main(void)
- {
- printf("%s", **++cpp);
- printf("%s", *--*++cpp+3);
- printf("%s", *cpp[-2]+3);
- printf("%s\n", cpp[-1][-1]+1);
- return 0;
- }
指针比较繁琐,仔细点应该不会有问题,分析如下:
第一个输出如下:
第二个输出如下:
第三个输出如下:
第四个输出如下:
最后结果为POINTERSTEW
参考文章:http://blog.youkuaiyun.com/hopeztm/article/details/8008345
2、怎么讲内存地址为0x12ff7c上存入整数0x100?
- int *p = (int *)0x12ff7c;
- *p = 0x100;
或者
- *(int*) 0x12ff7c = 0x100;
3、
- int a[3];
- a[0]=0; a[1]=1; a[2]=2;
- int *p, *q;
- p=a;
- q=&a[2];
- //a[q-p] = ?
答案:a[q-p] = 2;
q为a[2]的地址,p为a[0]的地址,两个地址的差值p-q就是a[2]与a[0]之间的地址差,则a[q-p]=a[2]
q=a; //q=&a[0];
q=p+2; //q=&a[2];
这样更容易理解
4、下面输出的值是多少?
- #include <stdio.h>
- void func(int* ptr, int &value)
- {
- ptr = &value;
- }
- int main()
- {
- int i = 10, j = 5;
- int *ptr = &i;
- func( ptr, j);
- printf("%d", *ptr);
- return 0;
- }
答案是:10.
这里主要涉及到函数参数问题,同int类型一样,指针也存在引用的问题。如果上面的函数声明改为:
void func (int* &ptr, int &value);
则答案就是5了。
5、填空:
- struct Test
- {
- int Num;
- char *pcName;
- short sDate;
- char cha[2];
- short sBa[4];
- }*p;
假设p 的值为0x100000。如下表表达式的值分别为多少?
p + 0x1 = 0x___ ?
(unsigned long)p + 0x1 = 0x___?
(unsigned int*)p + 0x1 = 0x___?
答案:
p + 0x1 的值为0x100000+sizof(Test)*0x1。此结构体的大小为20byte,内存对齐。所以p +0x1 的值为:0x100014。(20的16进制是14)
(unsigned long)p + 0x1 的值呢?这里涉及到强制转换,将指针变量p 保存的值强制转换成无符号的长整型数。任何数值一旦被强制转换,其类型就改变了。所以这个表达式其实就是一个无符号的长整型数加上另一个整数。所以其值为:0x100001。
(unsigned int*)p + 0x1 的值呢?这里的p 被强制转换成一个指向无符号整型的指针。所以其值为:0x100000+sizof(unsigned int)*0x1,等于0x100004。
6、
用变量a给出下面的定义
a) 一个整型数
b)一个指向整型数的指针( A pointer to an integer)
c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)r
d)一个有10个整型数的数组( An array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers)
f) 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )
答案是
a) int a; // 一个整型数 An integer
b) int *a; // 一个指向整型数的指针 A pointer to an integer
c) int **a; // 一个指向指针的的指针 A pointer to a pointer to an integer
d) int a[10]; // 一个有10个整型数的数组 An array of 10 integers
e) int *a[10]; // 一个有10个指针的数组 An array of 10 pointers to integers
f) int (*a)[10]; // 一个指向有10个整型数数组的指针 A pointer to an array of 10 integers
g) int (*a)(int); // 一个指向函数的指针 A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // 一个有10个指针的数组,指向一个整形函数并有一个整形参数 An array of 10 pointers to functions that take an integer argument and return an integer
7、引用与指针有什么区别?
答案:三个方面的区别:
(1)引用访问一个变量是直接访问,而指针是间接访问。
(2)引用是一个变量的别名,本身不单独分配自己的内存空间,而指针有自己的内存空间。
(3)引用在开始的时候就绑定到了一个内存空间(开始必须赋初值),所以他只能是这个内存空间的名字,而不能改成其他的,当然可以改变这个内存空间的值.
8、如何判断一段程序是由C 编译程序还是由C++编译程序编译的?
- #ifdef __cplusplus
- cout<<"c++";
- #else
- cout<<"c";
- #endif
9、引用与多态的关系
引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。(回答欠妥当)
10.将“引用”作为函数参数有哪些特点?
(1)传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。
(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。
(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。
11.为什么拷贝构造函数的形参必须是引用类型?
假设拷贝构造函数的形参为值传递,则编译器会调用拷贝构造函数将实参存储到一个副本中,这样就进入了一个死循环
12.什么时候用常引用(const &)
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。如果是非const引用,需要注意一下规范,请看下面code
那么在什么情况下会产生临时变量呢,两种情况:1.形参与实参的类型不同 2.不是左值
13、不运行程序,问下面代码的输出是什么?
- #include<iostream>
- using namespace std;
- int main()
- {
- char *str[]={"welcome","to","Fortemedia","Nanjing"};
- char**p=str+1;
- str[0]=(*p++)+2;
- str[1]=*(p+1);
- str[2]=p[1]+3;
- str[3]=p[0]+(str[2]-str[1]);
- cout<<str[0]<<endl;
- cout<<str[1]<<endl;
- cout<<str[2]<<endl;
- cout<<str[3]<<endl;
- return 0;
- }
解答:
首先在line 5声明一个指针数组,而str的值就是数组的起始地址值,str的值被默认解析成char **变量的值。
line6声明了一个2级指针,char**p=str+1;由于str是char**型,即str指向的类型是char *型的,所以p的值是(int)str+sizeof(char*),显然p指向了str的第二个元素即str[1]的地址。
line7 :(*p++)+2;,由于后置运算符++优先级比*高,所以先进行++运算,p的值变为(int)p+sizeof(char*),,显然此时p指向了str[2]的地址,再进行*运算,由于后置是++返回未变化的p的值,取到了str[1]的值,即指向字符串"to"的指针的值,由于*p类型是char*的所以](*p++)+2;最终str[0]指向了“to”结尾的'\0'所以输出str[0]时为空。
line8:str[1]=*(p+1);,显然str[1]指向了字符串"Nanjing"的首地址。cout<<str[1]<<endl;输出字符串Nanjing
line9:很显然cout<<str[2]<<endl;输出jing
line10:由于在line7分析到p指向了str[2]的地址,由于line9中,把&str[2]~&str[2]+3里的数据修改成了字符创"jing"的首地址。str[2]-str[1] = 3,所以最终cout<<str[3]<<endl; 输出g。