一.C语言的 &和* []
1. &表示取内存地址;
比如:int a=5; &a 得到的是内存地址,
(内存地址是数字,比如某个内存地址:0000002235D3F670);
2.*有两种含义 ,
1)数据类型后面的*表示指针变量用。如:int *b;int c=22;b=&c;
2)没有数据类型的,表示取值, 比如:"int *b;int c=22;b=&c; *b"中的第二个*;
3.优先级: [] * &
[]是一级, *和&是二级 ,而且* 比 & 先算
总之, [] > * > &
4.变量的构成:包括变量名、变量值、变量值的内存地址、变量名的内存地址 ,变量的地址一般值变量值的内存地址。
4.指针是什么?
带有指向的针,指向内存地址的针。指针变量是存放内存地址的变量
5.处理数组的指针和存指针的数组
1) int *g[5];是存指针的数组,存放指针的数组
int a5[3][5] = {{1, 2, 3, 4, 44}, {5, 6, 7, 8, 88}, {9, 10, 11, 12, 1212}};
int *h[5];
h[0] = a5;
h[1] = a5+1;
h[2] = a5+2;
printf("*(h[0]) %d\n", *(h[0]));
printf("*(h[1]) %d\n", *(h[1]));
printf(" *(h[2]) %d\n", *(h[2]));
2) int (*g)[5] 是处理数组的指针,, g和g+1是地址 ,而且g比(g+1)大20;
因为int类型是4个字节,中括号[]中是5, 计算公式 sizeof(int)*5;
int(*g)[5];
int a2[3][5] = {{1, 2, 3, 4,44}, {5, 6, 7, 8,88}, {9, 10, 11, 12,1212}};
g = a2;
printf("(g+1) %d\n", (g + 1));
printf(" g %d", g);
由于 (g + 1)和g是内存地址,所以每次都不一样, 而且会出现负数,当负数时可能还不是相差20;
三.二维数组和指针的代码:
这些代码都是英文标点符号,可以直接复制执行;然后看结果
int main() {
//申明一个数组
int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
/*******行地址*******/
printf("/*******行地址*******/\n");
//1.二维数组 变量a加n,获得第(n+1)个子数组的内存地址
printf("a %p\n", a);//整个数组地址的内存地址/以及第一个子数组内存地址
printf("a+1 %p\n", a + 1);//第二个子数组内存地址
printf("a+2 %p\n", a + 2);//第三个子数组内存地址
//2.一维数组 变量b加n,获得第(n+1)个元素的内存地址
int b[4] = {33, 44, 55, 66};
printf("b %p\n", b);//数组地址的首地址
printf("b+1 %p\n", b + 1);//数组第二个元素地址
printf("b+2 %p\n", b + 2);//数组第三个元素地址
/*******行地址的值*******/
printf("/*******行地址的值*******/\n");
//3..二维数组 变量a中,*(a+n),获得第(n+1)个子数组的内存地址,
printf("*a %x\n", *a);//第一个子数组第一个元素地址 a和*a是一样的
printf("*(a+1) %x\n", *(a + 1));;//第二个子数组第一个元素内存地址
printf("*(a+2) %x\n", *(a + 2));//第三个子数组第一个元素内存地址
printf("(*(*a)) %x\n", (*(*a)));//第一个子数组第一个元素的值
/*******行内存地址的值*******/
printf("/*******列内存地址的值 真值*******/\n");
//4..二维数组 变量a中,*(*(a+n)+j),获得第(n+1)个子数组的第(j+1)个元素的值
printf("**a %x\n", **a);//第一个子数组第一个元素的值
printf("*(*a+1) %x\n", *(*a+1));//第一个子数组第一个元素的值
printf("**(a+1) %x\n", **(a + 1));//第二个子数组第一个元素的值
printf("*(*(a + 1)+1) %x\n", *(*(a + 1)+1));//第二个子数组第二个元素的值
printf("**(a+2) %x\n", **(a + 2));//第三个子数组第一个元素的值
printf("*(*(a + 2)+1) %d\n", *(*(a + 2)+1));//第三个子数组第二个元素的值
//以上比较繁琐
printf("/*******取值*******/\n");
int(*row)[4];//用于处理数组的指针
int *col;//申明一个指针
row = a;
col = a[0];
//中括号有引用取值的意思
//4..二维数组 变量a中,row[n]获得第(n+1)个子数组的内存地址
printf("row[0] %x\n", row[0]);//第一个子数组的内存地址
printf("row[1] %x\n", row[1]);//第二个子数组的内存地址
printf("row[2] %x\n", row[2]);//第三个子数组的内存地址
printf("/*******(row[i]取值*******/\n");
//4..二维数组 变量a中,*(row[n] + j))获得第(n+1)个子数组的第(j+1)个元素的值
printf("*(row[0]+1) %x\n", *(row[0] + 1));//第一个子数组的第二个元素
printf("*(row[1]+2) %x\n", *(row[1] + 2));//第二个子数组的第三个元素
printf("/*******(col取值*******/\n");
printf("*(col+0+1) %x\n", *(col + 0 + 1));//第一个子数组的第二个元素
printf("*(col+1*4+2) %x\n", *(col + 1 * 4 + 2));//第二个子数组的第三个元素
printf("/*******(a[i]+j取地址*******/\n");
//5..二维数组 变量a中,a[n]+j获得第(n+1)个子数组的第(j+1)个元素的内存地址
printf("a[0]+0 %x\n", a[0]+0);//第一个子数组的第一个元素的内存地址
printf("a[0]+1 %x\n", a[0]+1);//第一个子数组的第二个元素的内存地址
printf("a[0]+2 %x\n", a[0]+2);//第一个子数组的第三个元素的内存地址
printf("a[0]+3 %x\n", a[0]+3);//第一个子数组的第四个元素的内存地址
printf("a[1]+0 %x\n", a[1]+0);//第二个子数组的第一个元素的内存地址
//6..二维数组 变量a中,*(a[n]+j)获得第(n+1)个子数组的第(j+1)个元素的值
printf(" *(a[1]+0) %x\n", *(a[1]+0));//第一个子数组的第一个元素的值
return 0;
;
}
四.输出结果
/*******行地址*******/
a 0000002235D3F5D8
a+1 0000002235D3F5E8
a+2 0000002235D3F5F8
b 0000002235D3F668
b+1 0000002235D3F66C
b+2 0000002235D3F670
/*******行地址的值*******/
*a 35d3f5d8
*(a+1) 35d3f5e8
*(a+2) 35d3f5f8
(*(*a)) 1
/*******列地址的值 真值*******/
**a 1
*(*a+1) 2
**(a+1) 5
*(*(a + 1)+1) 6
**(a+2) 9
*(*(a + 2)+1) 10
/*******取值*******/
row[0] 35d3f5d8
row[1] 35d3f5e8
row[2] 35d3f5f8
/*******(row[i]取值*******/
*(row[0]+1) 2
*(row[1]+2) 7
/*******(col取值*******/
*(col+0+1) 2
*(col+1*4+2) 7
/*******(a[i]+j取地址*******/
a[0]+0 35d3f5d8
a[0]+1 35d3f5dc
a[0]+2 35d3f5e0
a[0]+3 35d3f5e4
a[1]+0 35d3f5e8
*(a[1]+0) 5