[c/c++精选题目]07-指针和数组

Posted 刘望

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[c/c++精选题目]07-指针和数组相关的知识,希望对你有一定的参考价值。

Note1: *p和p

void fun(int *p)//形参 不分配空间
{
*p += 100;
int a = 10;
p = &a;
}
int main()
{
int x = 10;
int *s = &x;
fun(s);
cout << *s <<endl<< x; // 110 110
return 0;
}

分析:在fun()结束后,s仍然指向x。对p本身的改变,对s不变

Note2:

void Swap_a(int a, int b)//传值操作:形参改变,但是实参不变
{
int c = a;
a = b;
b = c;
}
void Swap_b(int &a, int &b)//传入引用:可以改变实参
{
int c = a;
a = b;
b = c;
}
void Swap_c(int *p1, int *p2)
{
int c = *p1;
*p1 = *p2;
*p2 = c;
}
int main()
{
int x = 10, y = 20;
Swap_a(x, y);
cout << x << " " << y << endl; //NO
Swap_b(x, y);
cout << x << " " << y << endl; //YES
Swap_c(&x, &y);
cout << x << " " << y << endl; //YES

return 0;
}

Note3:数组名的第二个例外:取地址

int main()
{
int a = 10;
int ar[] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 };
cout << sizeof(ar) << endl;//数组名的第一个例外:40

//1 从右到左。2 遇见(),先内后外
int *p[10];//[10]数组,放的是整型指针 p是数组名,数组开辟10个大小空间
int *r = &a;
int(*s)[10] = &ar;//(*s)指针(开辟4个字节,存放数组地址),指向的数组:开辟10个大小,里面放的是整型类型 这个10 不可以少,和ar保持一致
return 0;
}

1 p和ar的区别:p数组放的是整型指针(四个字节)。
2 cout << sizeof(ar)<<" "<<sizeof(s)<< endl; 40 4
3 int(*s)[10] = &p;这是错误的,不可以 大小相同,类型不同
4 int * (*s)[10] = &p;就可以了

能指向的三个条件:大小 类型 连续空间,

Note4:

数组名的第三个例外:初始化引用,让这个引用代表整个数组

int main()
{
int ar[] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 };
cout << sizeof(ar) << endl;//数组名的第一个例外:40

int &br1 = ar[0];//12的别名
int(&br2)[10] = ar;//数组ar的引用

int *p[10];//[10]数组,放的是整型指针 p是数组名,数组开辟10个大小空间
int(*s)[10] = &ar;//(*s)指针(开辟4个字节,存放数组地址),指向的数组:开辟10个大小,里面放的是整型类型
int* (&br3)[10] = p;//数组p的引用
return 0;
}

Note5:二级指针

int main()
{
int a3 = 0, a2 = 0, a1 = 0, a0 = 0;
int *p3 = &a3, *p2 = &a2, *p1 = &a1, *p0 = &a0;
int **s = &p0;

return 0;
}

[c/c++精选题目]07-指针和数组

一级指针:
type *p=0;
p+=1;//p+=sizeof(type)*1;

二级指针:
type *s;//二级指针
s+=1;//s+=sizeof(type
)*1; 4
*s+=1;//*s+=sizeof(type)1; //此时s 是一级指针 类型可能会变

Note6:

int main()
{
int ar0[3][4] = { 0 };
int(*s)[4] =ar0;// s是二级指针 s+1是加一个数组 s指向数组的地址
cout << "ar0[2][2]:" << ar0[2][2] << endl;
*(*(s + 2) + 2) = 1;
cout << "ar0[2][2]:" << ar0[2][2] << endl;
return 0;
}

Note7:

void fun(int &a)
{
int *p = &a;
a += 10;
*p += 10;
}
int main()
{
int x = 10;
int &r = x;
fun(x);
fun(r);
cout << x << endl;//50
return 0;
}

Note8:

int a = 10, b = 20;
int const *p = &a;

int *s1 = p; //error
int const *s2 = p;
int * const s3 = p; // error
const int * const s4 = p;

分析:第一个 第三个有错:能力扩大,通过解引用 进而改变*p的值

Note9:

int a = 10, b = 20;
int * const p = &a;

int *s1 = p;
int const *s2 = p;
int * const s3 = p;
const int * const s4 = p;

Note10:

对应于 Note7, 引用被编译器处理为 自身不可改变的 指针

void fun(int * const a)//用指针模拟逻辑上的引用
{
int *p = a;
*a += 10;
*p += 10;
}
int main()
{
int x = 10;
int * const r = &x;
fun(&x);
fun(r);
cout << x << endl;//50
return 0;
}

Note11:

这个不可改变的指针 在使用时(使用引用),常常解引用操作。

	int c = 10;
int &b = c;
int *p = &c;
b = 100;
*p = 100;

反汇编:

int c = 10;
00E646B2 mov dword ptr [c],0Ah
int &b = c;
00E646B9 lea eax,[c]
00E646BC mov dword ptr [b],eax
** int *p = &c; **
00E646BF lea eax,[c]
00E646C2 mov dword ptr [p],eax
b = 100;
00E646C5 mov eax,dword ptr [b]
00E646C8 mov dword ptr [eax],64h
*p = 100;
00E646CE mov eax,dword ptr [p]
00E646D1 mov dword ptr [eax],64h

Note12:

数组名和指针的区别

int main()
{
int ar[10] = { 1, 2, 3, 4 };
int *p = ar;
p[1] = 6;// *(p+1)
ar[1] = 6;// *(ar+1)
return 0;
}

p[1] = 6;
00F24BDE mov eax,4
00F24BE3 shl eax,0
00F24BE6 mov ecx,dword ptr [p] //先从内存中访问p
00F24BE9 mov dword ptr [ecx+eax],6
ar[1] = 6;
00F24BF0 mov eax,4
00F24BF5 shl eax,0
00F24BF8 mov dword ptr ar[eax],6

Note13:

int main()
{
int ar[5][2] = { 1,2,3,4,5,6,7,8,9,10 };
int(*p)[2] =&ar[1];// p是指向数组的指针
cout << p[1][3] << endl;
int *s = ar[1];// *(ar+1)
cout << s[3] << endl;
return 0;
}

Note14:

int main()
{
int ar[3][4];
sizeof(ar);//12*4
int(*p)[3][4] = &ar;//p是指向二维数组的地址 p+1是48
int(&br)[3][4] = ar;
int(*s)[4] = ar;//s指向一位数组的地址 ar的首元素是个一位数组
return 0;
}