一、基本问题
(1)一元运算符&可用于取一个对象的地址
char c;
p=&c;//p是指向c的指针
需要注意的是:地址运算符只能用于内存中的对象即变量与数组元素,他不能作用于表达式、常量式、register类型变量
(2)一元运算符*是间接引用运算符,它作用于指针时,将访问指针所指向的对象。
int x=1,y=2,z[10];
int *ip;//ip是指向int类型的指针
ip=&x;//ip指向x
y=*ip;//y的值现在为1
*ip=0;//x的值为0
ip=&z[0];//ip指向在z[0]
需要注意的是:每种指针必须指向某种特定的数据类型
y=*ip+1;//*ip指向的对象的值取出并加1
*ip+=1等价于++*ip等价于(*ip)++//ip指向对象的值加1
*ip++则表示将ip进行加1运算
(3)关于指针
需要注意的是:下面的几种是有效的指针运算
1.相同类型之间的赋值运算。指针也是变量,下面的操作是正确的
int *iq;
iq=ip;//将ip中的对象拷贝到iq中,这样iq也指向ip所指向的对象。
2.指针同整数之间的加减运算3.如果指针p、q指向同一数组的成员,那么平p<q时,q-p+1就是位于p和q之间元素数目。
4.指针也可以初始化,只能是0或者地址表达式;指针与整数不能相互转化,但0是意外。
int * a =10;(错误写法,给指针赋值必须为地址,*p为所指向变量的值)
char * pstr="aslgkjklahjkla";
(4)数组与指针1.举例说明他们的关系int a[10];int *pa;pa=&a[0]=a;//pa的值是数组元素a[0]的地址 数组名代表数组最开始元素的地址*(pa+i)=a[i]//truef(&a[2])等价于f(a+2)2.区别指针是个变量,pa=a和pa++合法;数组名不是变量,a=pa;a++非法;
(5)其他C/C++零散但笔试面试中需要注意的地方1.‘1’是字符占一个字节,“1”是字符串占两个字节。2.(int)(a+b)表示把a+b转型;(int)a+b表示把a转型再加b。3.假设a=5,++a(是为6),a++(是为5),进行了++a和a++后下面的程序再用到a的话变量a值是6。技巧:++在前先加后用,++在后先用后加4.(2,3,4)的表达式数值就是4逗号表达式的优先级别最低5.char a=getchar()是没有参数的从键盘得到你输入的一个字符给变量aputchar('y')把字符y输出到屏幕中。6.break和continue区别。break破了整个循环,看到break退出整个循环;continue继续循环运算,要结束本次循环,就是循环体内剩下的语句不再执行,跳到循环开始然后判断循环条件,进行新一轮循环。举例说明:
#include<stdio.h>int main(){char grade='C';switch (grade){case 'A':case 'B':printf("good");case 'C':case 'D':printf("Pass");default:printf("error");}}输出结果:Passerror解析:如果case 'C'后添加break后输出空。
7.a=3!=2和(a=3)!=2 第一个a=1,第二个a=3!=的级别高于=8.关于二维数组需要注意的地方a[3][3]={1,2,3,4,5,6,7,8,9};a是二维数组名它是行指针。分析二维数组可以按下面考虑:
第一列 第二列 第三列
a[0] 1 2 3 第一行 a[1] 4 5 6 第二行 a[2] 7 8 9 第三行
*(a[0]+1)等价于a[0][1]*(a[1]+2)等价于a[1][2]等价于*(a+1)[2]等价于再变成*(*(a+1)+2)第二行元素往后面跳二列
二、传递动态内存
1.下面5个函数哪个能够成功进行两个数的交换?#include<iostream>using namespace std;
void swap1(int p,int q){int temp;temp=p;p=q;q=temp;}
void swap2(int *p,int *q){int *temp;*temp=*p//不是指向是拷贝*p=*q;*q=*temp;}
void swap3(int *p,int *q){int *temp;temp=p;p=q;q=temp;}
void swap4(int *p,int *q){int temp;temp=*p;*p=*q;*q=temp;}
void swap5(int &p,int &q){int temp;temp=p;p=q;q=temp;}int main(){int a=1,b=2;//swap1(a,b);//swap2(&a,&b);//swap3(&a,&b);//swap4(&a,&b);//swap5(a,b);cout<<a<<""<<b<<endl;return 0;}
答案:swap4函数和swap5函数
2.下面程序测试后会有什么结果?#include<iostream>void GetMemory(char *p,int num){p=(char *)malloc(sizeof(char)*num);};int main(){char *str=NULL;GetMemory(str,100);strcpy(str,"hello");return 0;}
答案:程序崩溃。因为GetMemory并不能传递动态内存,Test函数的str一直都是NULL。详细解释:p申请了新的内存,只是把p所指向的内存地址改变了,但是str丝毫未变。因为函数GetMemory没有返回值,因此str并不指向p所申请的那段内存。拓展:改法(1)#include<iostream>void GetMemory(char **p,int num){*p=(char *)malloc(sizeof(char)*num);//指针参数申请内存};int main(){char *str=NULL;GetMemory(&str,100);strcpy(str,"hello");cout<<*str<<endl;//输出hcout<<str<<endl;//输出hellocout<<&str<<endl;//输出0*22f7creturn 0;}拓展:改法(2)
#include<iostream>void *GetMemory(char *p,int num){p=(char *)malloc(sizeof(char)*num);return p;};int main(){char *str=NULL;GetMemory(str,100);strcpy(str,"hello");return 0;}
3.这个问题有什么问题?该如何修改?char *strA(){char str[]="hello world";return str;}答案:str存放的地址是函数栈"hello world"的首地址。因为这个函数返回的是局部变量的地址,当调用这个函数后,这个局部变量str就释放了,所以返回的结果是不确定的且不安全,随时都有被收回的可能。
改法1:const char* strA(){char *str="hello world";return str;}
改法2:const char* strA(){static char str[]="hello world";//static开辟一段静态存储空间。return str;}
4.下列程序会在哪一行崩溃?
struct S{
int i;
int * p;
};
main()
{
S s;
int *p=&s.i;//相当于int *p; p=&s.i;
p[0]=4;
p[1]=3;
s.p=p;
s.p[1]=1;
s.p[0]=2;//崩溃
}
解析:当执行p[0]=4和p[1]=3的时候,p始终等于&s.i;
s.p=p时s.p存了p的值也就是&s.i;那么s.p[1]=*(&s.i+1)即s.i的地址加1也就是s.p
三、函数指针
1.函数指针的基本了解(第二列为举例)
函数指针 void (*f)() 函数返回指针 void *f() const指针 const int* 指向const的指针 int* const;
指向const的const指针 const int* const int(*ptr)[]是一个指向整形数组的指针 int *ptr[]和int *(ptr[])相同,指针数组,ptr[]里存的是地址。
接受任何类型参数并返回int类型参数 int func(void *ptr)
2.关于函数指针比较难理解的几处
float(**def)[10] def是一个二级指针,指向的是一个一维数组的指针,数组的元素都是float double *(*gh)[10] gh是一个指针,它指向的是一个一维数组,数组元素都是doubel* double(*f[10])() f是一个数组,f有10个元素,元素都是函数的指针,指向的函数类型是没有参数且返回double的函数
四、指针数组和数组指针
1.以下程序的输出是?#include<stdio.h>#include<iostream>using namespace std;int main(){int v[2][10]={{1,2,3,4,5,6,7,8,9,10}, {11,12,13,14,15,16,17,18,19,20}};int (*a)[10]=v;//数组指针cout<<**a<<endl;//输出1cout<<**(a+1)<<endl;//输出11cout<<*(*a+1)<<endl;//输出2cout<<*(a[0]+1)<<endl;//输出2cout<<*(a[1])<<endl;//输出11}需要注意的是:**a表示{1,2,3,4,5,6,7,8,9,10}**(a+1)表示{11,12,13,14,15,16,17,18,19,20}*(*a+1)表示2
2.下面程序输出结果是什么?#include<iostream>using namespace std;main(){char* a[]={"hello","the","world"};char**pa=a;pa++;cout<<*pa<<endl;}输出:the解析:指针的指针的问题。
3.下面的操作会输出什么?为什么?
答:输出结果应该是这样:
待续未完……