C语言学习笔记
指针
指针与基本数据类型
- 指针是什么:
指针式一种数据类型,就像int float,int装整形数据,float装浮点型数据,指针装地址数据
- 声明一个指针的形式:
int *q,*p;
double *d;
float *f;
short *s;
int a = 12;
p = &a;
q = &a-1;
printf("%p,%p,%p,%p", p, &a, &p, q)
000000000062FE0C,000000000062FE0C,000000000062FE10,000000000062FE08
指针操作指向空间
int a = 12;
int *p = &a;
1、读
printf("%p,%d,%d\n", p, *p, a);
2、写
*p = 123;
printf("%p,%d,%d\n", p, *p, a);
3、取地址
printf("%p,%p,%p\n", p, &*p, &a);
return 0;
这样的输出结果是:
000000000062FE14,12,12
000000000062FE14,123,123
000000000062FE14,000000000062FE14,000000000062FE14
这里的*可以叫做内存运算符,例如p代表的是a的地址,那么*p就是p的地址里装的数据,即*p == a。对*p进行运算也就改变了a的数据。
利用指针遍历一维数组地址
int a[5] = {9,7,5,3,1};
int *p = &a[0];
printf("%p,%p,%p,%p,%p\n", p, p+1, p+2, p+3, p+4);
printf("%p,%p,%p,%p,%p\n", &a[0], &a[1], &a[2], &a[3], &a[4]);
000000000062FE00,000000000062FE04,000000000062FE08,000000000062FE0C,000000000062FE10
000000000062FE00,000000000062FE04,000000000062FE08,000000000062FE0C,000000000062FE10
- 由此可见p+1==a[0]+1,这其实就是下标运算的意义。
利用指针遍历一维数组数据
- 根据*内存运算符的意义,我们可以直接用循环打印出数组的各项数据:
int i;
for (i = 0 ; i < 5 ; i++)
{
printf ("%d\t", *(p+i));
}
指针与下标运算
- 下标运算的本质:地址+[偏移量](例如a[0],a[1])
- 也就是说a[2]==p[2]
- 准确来说,下标运算,不是数组专属,只是一个运算符。数组可以用是因为它符合了下标运算符的使用条件,地址+[偏移量]。我们的指针也是完全可以的。
- 两个简单等式:*(p+2)==p[2],*(*(p+2)+3)==p[2][3]
- 下标运算的实质:前后两个值相加得到的地址所包含的数据
指针数组
int b=4,c=3,d=7,e=8,f=1;
int *a[5] = {&b,&c,&d,&e,&f};
int i;
for (i = 0 ;i <= 4 ; i++)
printf("%p,",a[i]);
000000000062FE18,000000000062FE14,000000000062FE10,000000000062FE0C,000000000062FE08,
指针数组拉链结构
int b[3] = {1,2,3};
int c[2] = {4,5};
int d[4] = {6,7,8,9};
int e[5] = {10,11,12,13,14};
int f[2] = {15,16};
int *a[5] = {&b[0],c,d,e,f};
printf("%d\n",a[2]\[2]);
- 和二维数组的访问格式是一样的,意义也是一样的。但是内存结构是不一样的,或者说本质不一样。每个小数组大小可以不同,但是数据类型必须相同。
- 可以参照以下表格理解拉链结构:
-
| b | c | d | e | f |
---|
a | 1 | 4 | 6 | 10 | 15 |
| 2 | 5 | 7 | 11 | 16 |
| 3 | | 8 | 12 | |
| | | 9 | 13 | |
| | | | 14 | |
数组指针
- 首先再次明确两个公式:
a == &a[0],&a[0]+1 == &a[1]
- &a是对于整个数组的数组类型的地址
int a[5] = {3,4,5,2,6}
int *p = &a[4];
int *(p1)[5] = &a;
printf ("%p,%p\n",&(*p1)[2],&a[2]);
000000000062FDF8,000000000062FDF8