C语言学习笔记(五)
int a[5]={1,2,3,4,5}; int *p=a;
首地址(第一个元素的地址): a &a(整个数组的首地址) p &a[0]
第i个元素的地址: a+i-1 &a+i-1 p+i-1 &a[i-1]
首地址元素(第一个元素): a[0] *a *p
第i个元素: a[i-1] p[i-1] *(a+i-1) *(p+i-1)
------------------------------------------------------------------------
a 是数组第一个元素的地址,也就是a[0]的地址,a+1是下一个元素的地址
&a 是整个数组的首地址,而&a+1是下一个数组的首地址
&a+1:取数组a的首地址,该地址的值加上sizeof(a)的值,即&a+5*sizeof(int)
+也就是下一个数组的首地址,显然当前指针已经越过了数组界限。
int *p = (int *)(&a+1); 这是把&a+1算出来的地址强制转换为int *类型赋值给p;
int* p1[5] —— 指针数组, 用于存放指针类型的数组,p1为数组名
指针类型数组,[]比*号优先级高,所以p1先和[5]结合成p1[5]组成数组,类型是int *
int*p1[10];
p1 -- > | int* | int* | int* | int* |int* |
int (*p2)[5] —— 数组指针,p2为指针变量名,它代表的是整个数组的首地址,而不是第一个元素的地址
一个指针指向着这个int类型的数组
p2 --> |int | int | int | int | int |
p2+1 这会每次夸个5个字节
char a[5] = {'A', 'B', 'C', 'D'};
char(*p3)[10] = &a;
char(*p4)[10] = a; //类型会警告,a是数组第一个元素的地址
行参与实参传递的问题
实参 行参
数组的数组 charc[8][10]; char(*)[10]; 数组指针
指针数组 char * c[10]; char **c; 指针的指针
数组指针 char (*c)[10]; char(*c)[10]; 不改变
指针的指针 char**c; char**c; 不改变
char * arr[2]={"abc","edf"}; chararr[2]={'a','b'}; inta=10;
char ** pp_arr = NULL; char *p_arr = arr; int *p=&a;
pp_arr = arr; char **pp_arr = &p_arr; int**pp_num=&p;
*pp_arr = arr[0]; *pp_arr = p_arr; *pp_num=p;
*(pp_arr+1) = arr[1]; *(*pp_arr+1)= 'c'; **pp_num=15;
printf("%s\n",*(pp_arr+1)); printf("%c\n", *(*pp_arr+1)); printf("%d\n",**pp_num);
===============================================================================================
< C语言学习笔记(完)>