经常使用STL导致数组与指针都陌生了,复习总结一下
C/C++里指针确实更高效了,也更复杂了
数组
- 数组的创建
type_t arr_name[const_n];
//type_t指数组的元素类型,const_n指常量表达式
int arr[10];//is ok
- 数组的初始化
int arr1[10];//不进行初始化,存放未知值
int arr2[10]={1};//进行初始化,则未进行初始化位置初始化为0
int arr3[]={1,2,3,4,5};
//首先要知道 "a"---是const char*类型,并且"a"其实是有\0的,所以sizeof("a")=2;
//'a'---是char类型;sizeof('a')=1;
char ch1[]="abc";//sizeof(ch1)=4;
char ch2[]={'a','b','c'};//sizeof(ch2)=3;由于没有'\0',打印的时候会出现烫烫烫
char ch3[10]={'a'};//sizeof(ch3)=10;其余空间初始化为0,%s打印的时候对应的是空格
char ch4[10]="a";//sizeof(ch4)=10;其余空间初始化为0,
printf("%s",ch1);//ch1---char * %s打印
printf("%c",ch1[0]);//ch1[0]---char %c打印
注意:数组传参的时候需要传递数组长度,因为参数仅仅传递的是数组首地址
- 二维数组
type_t arr_name[const_n][const_n];
int arr1[5][5];
int arr2[][5]={1,2,3,4,5,6,7};//第二列未初始化数据初始化为0
注意:二维数组传参需要传二级指针,并且需要传行数(row)与列数(column)
void testS1()
{
int arr2[][5] = {1,2,3,4,5,6,7};
printvv((int **)arr2, 2, 5);//强制转换为int**
}
void printvv(int **arr,int row,int col)
{
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col; ++j)
{
printf("%d ", *((int *)arr+i*col+j));//先解引用为1级指针,再进行操作,利用二维数组在内存上连续的性质
}
printf("\n");
}
}
指针
- 对指针的运算操作,++步长是指针所指向对象的大小
double a = 10;
int b = 10;
double *p1 = &a;
int *p2 = &b;
printf(" p1:%d\n", p1++);
printf("++p1:%d\n", p1);
printf(" p2:%d\n", p2++);
printf("++p2:%d\n", p2);
输出
p1:11533312
++p1:11533320
p2:11533300
++p2:11533304
- ++指针,将使指针指向前一个元素;–指针,指针指向后一个元素
- 指针-指针=中间元素的个数,前提是两个指针类型相同,并且指向同一块内存
指针的使用
//一些线上OJ经常会遇到的题,平时不要这样写,容易挨揍
int a1[5]={1,2,3,4,5};
int *ptr=(int *)(&a1+1);//&a是int**类型,是指向a地址的地址,对指向(int a[5])类型的指针+1操作之后,则增加整个数组的长度,之后又被强转为int*
//对于这里的(int a[5])类型,编译器是这样提示的,也确实好理解多了
printf("%d,%d",*(a1+1),*(ptr-1));//输出2,5
int a2[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a2[0];//隐士类型转换,(int a2[3][2])转换为(int *)可以理解为转换为了(int a[2])
printf("%d", p[0]);//可以看成a2[0][1],所以输出位1