一、参数引用的常见错误
找错
#include <iostream>
using namespace std;
class Test
{
public:
void f(const int& arg);
private:
int value;
};
void Test::f(const int& arg)
{
arg = 10;
cout<<"arg = "<<arg<<endl;
value = 20;
}
int main()
{
int a = 7;
const int b = 10;
int &c = b;
const int& d = a;
a++;
d++;
Test test;
test.f(a);
cout<<"a = "<<a<<endl;
return 0;
}
第15行,错误,arg是常量引用,其值不能修改。
第24行,错误,b为常量,但是c不是常量引用,应写为:
const int &c = b;第28行,d为常量引用,其值不能改变。
二、指针和引用有什么区别
区别如下:
(1)初始要求不同。引用在创建时必须初始化,指针定义时可以不初始化。
(2)可修改性不同。引用一旦确定初始化对象,之后不能再改变,指针在任何时候都可以改变指向的对象。
(3)不存在NULL引用,引用必须指向某个对象,指针可以指向NULL,可以指向任意对象。
(4)测试的区别。引用不会指向NULL,在使用引用前不需要检查其合法性,指针需要经常测试。
(5)应用的区别。如果一旦指向一个对象后就不会改变指向,可以使用引用,如果存在指向NULL或需要指向不同对象的可能性,使用指针。
实际上,引用就是编译器为我们完成对指针操作的转换,在二进制层面,引用也是通过指针来实现的。总体来说,引用既有指针的效率,又有变量使用的方便性和直观性。
三、为什么传引用比传指针安全
原因:
因为引用不存在指向NULL的情况,且引用一旦被初始化,就不能改变,所以引用很安全。
对于指针来说,它可以随时指向别的对象,并且可以不被初始化,或为NULL,所以不安全,尤其是野指针,非常危险。
四、复杂指针的声明
用变量a给出下面的定义
a、一个整型数
b、一个指向整型数的指针
c、一个指向指针的指针,它指向的指针是指向一个整型数的。
d、一个有10个整型数的数组
e、一个有10个指针的数组,该指针是指向一个整型数的
f、一个指向有10个整型数数组的指针
g、一个指向函数的指针,该函数有一个整型函数并返回一个整型数
h、一个有10个指针的数组,该指针指向一个函数,给函数有一个整型参数并返回一个整型数
a、int a;
b、int *a;
c、int** a;
d、int a[10];
e、int* a[10];
f、int (*a)[10];
g、int (*a)(int);
h、int (*a[10])(int);
五、用指针赋值
#include <stdio.h>
int main()
{
char a[] = "hello, world";
char *pstr = a;
printf("%c\n", *(pstr+4)); //o
printf("%c\n", pstr[4]); //o
printf("%c\n", a[4]);
printf("%c\n", *(a+4));
*(pstr+4) += 1;
printf("%s\n", a); //hellp,world
return 0;
}
这里其实很简单,第6行中将字符串a首地址赋给pstr,之后pstr就指向了字符串a,8~11行其实都是输出“hello,world”中的第5个字母,即‘o’。
第13行中,去字符串的第四个字母,将其自加一,o的ascall加1即为p,所以14行输出“喝了两瓶“hellp,world”。
输出:
o
o
o
o
hellp, world
六、指针加减操作
看代码,写输出
#include <stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
int *ptr = (int*)(&a+1);
printf("%d\n", *(a+1));
printf("%d\n", *(ptr-1));
return 0;
}
这题主要就是a和&a的理解了,首先将a[5]看成分散的元素,a就是数组首元素地址,第8行输出的是数组首元素地址加一的数,即a[1] 2。
然后就是第6行的理解了,这个时候把a数组看成一个整体,&a表示取这个数组的地址,数组在内存中是线性分布的,&a+1就是这个数组最后一个元素之后的地址,ptr-1指向的就是a数组的最后一个元素。
a a+1 a+2 a+3 a+4 &a+1
__ __ __ __ __ __ __ __ __ |__ |__| __ | __| ___ _|_ __ __ __ __ __ __ __
|__|__|__|__|__|__|__|__|__|_1 |_2 |_3_|_4_|_5_|__|__|__|__|__|__|__|__|
输出:
2
5
七、指针比较
看代码,写输出
#include <iostream>
using namespace std;
int main()
{
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char* str5 = "abc";
const char* str6 = "abc";
char* str7 = "abc";
char* str8 = "abc";
cout<<(str1==str2)<<endl;
cout<<(str3==str4)<<endl;
cout<<(str5==str6)<<endl;
cout<<(str6==str7)<<endl;
cout<<(str7==str8)<<endl;
return 0;
}
str1、
str2、str3、str4都是在栈中分配的,内存中的内容都是“abc”加‘\0’,但它们的位置是不同的,因此16、17输出0.
str5、str6、str7、str8也是在栈中分配的,它们都指向“abc”字符串,注意“abc”存放在数据区,所以str5、str6、str7、str8其实指向的是同一块内存,因此18、19、20行输出1。
输出:
0
0
1
1
1
转载请注明原文地址: https://ju.6miu.com/read-20441.html