数组与指针
数组名有两个含义:
1. 代表整个整组 2. 代表首元素的地址
数组名看作是指针:首元素的地址 (&数组名[0])
数组元素与普通变量是一样的,数组元素也有自己的地址。
数组元素也有左值和右值,并且数组元素间的地址是相邻的。
数组名可以代表首元素的地址.
a => &a[0], 当数组名a当作指针来用时
数组名是保存第一个元素的地址的指针!!!
例如:
int a[4] = {0};
int*p = &a[2];
*p = 100;
输出 a: 0 0 100 0
int a[4] = {1,2,3,4};
int*p = a;// int *p = &a[0]
*p = 100;
printf("a[0] = %d\n", a[0]);//100
指针与数组的偏移(区别)
数组基地址编号:X
1. int a[10] = {1,2,3,4,5,6,7,8,9};
printf("a = %p, a+1 = %p, &a + 1 = %p\n", a, a+1, &a+1);a : 看作是指针 &a[0] 地址编号 :X
a+1 : a看作是指针 &a[0] 地址编号 :X+4
&a[0] + 1 ==> &a[1] 在原先的基础上 往后挪了1个int
==> typeof(&a[0]) ==> typeof(a[0])* ==>int*
&a+1: a 代表整个整组 地址编号 :X+40
&a + 1 ==> 在原先的基础上 往后挪了1个int[10]
typeof(&a) ==> typeof(a)* ==>int[10]*2. int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
printf("a = %p, a+1 = %p, &a[0] + 1 = %p, &a + 1 = %p\n", a, a+1, &a[0]+1, &a + 1);a : 看作是指针 &a[0] 地址编号 :X
a+1 : a看作是指针 &a[0]+1 ==> &a[1] 地址编号 :X+16
typeof(&a[0]) ==> typeof(a[0])* ==>int[4]*
typeof(&a[0]+1) ==>int[4]*
&a[0]+1 ==> &a[1] 地址编号 :X+16
&a + 1 : a 代表整个数组 &a+1 加了 1个int[4][3] 地址编号 :X+48
typeof(&a) ==> typeof(a)*==> int[4][3]*
多维数组与指针
- 数组名可以看作是指向第一个元素的指针,并且在数值上为第一个元素的地址。 数组名a, 如果把a当指针 a => &a[0]
- C语言所有数组都是一维数组!
int a[3][4]; a 里面有 3个元素, 每个元素都是一个int[4] 类型的对象 a 里面有3个数组,分别对应 a[0] a[1] a[2] a[0],a[1],a[2] 都是该数组的数组名
eg:
int a[3][4];
表达式 表达式的含义及类型 表达式的值
a 数组名 首元素的编号 &a[0]
1. 看作是指针:首元素的地址 &a[0] 在数值上:&a[0]=>&a[0][0]=>a=>&a
typeof(a) ==>typeof(&a[0]) 假设编号:X
typeof(a[0])*=>int[4]*
2. 代表整个数组
typeof(a) => int[4][3]
&a[0] 取第一行的地址 第一行的地址 &a[0]
取a[0]这个元素的地址 在数值上:&a[0]=>&a[0][0]=>a=>&a
typeof(&a[0])==>typeof(a[0])* 假设编号:X
==> int[4]* (默认代表数组)
a[0]:代表整个数组 typeof(a[0])==>int[4]
a[0]:看作是指针 &a[0][0],typeof(&a[0][0])==>int*
a[0] 相当于一个一维数组的数组名
&a[0][0] 在数值上:&a[0]=>&a[0][0]=>a=>&a
假设编号:X
1. a[0]:代表整个数组 typeof(a[0])==>int[4]
2. a[0]:看作是指针 &a[0][0],typeof(&a[0][0])==>int*&a[0][0] a[0][0] 这个元素的地址 &a[0][0]
typeof(&a[0][0]) ==> int* 在数值上:&a[0]=>&a[0][0]=>a=>&a
假设编号:Xa+1 取第二行的地址 第一行的地址 &a[1]
取a[1]这个元素的地址 在数值上:&a[1]=>&a[1][0]=>a+1
a : 看作是指针 假设编号:X+16
a+1 ==> &a[0] + 1
==> &a[1]
&a[1]&a+1 a数组整个挪动 int[4][3]个字节之后,
一个int[4][3]数组的首地址 假设编号:X+48
typeof(&a+1) ==> int[4][3]*
a[1]+2 a[1][2] 这个元素的地址 &a[1][2]
a[1] 看作是指针 &a[1][0] 数值上: X + 24
typeof(&a[1][0]) ==> int*
a[1] + 2 ==> &a[1][2]
typeof(a[1]+2) ==> typeof(&a[1][2])
==> int*
*(a+1)+2 a[1][2] 这个元素的地址 &a[1][2]
typeof(*(a+1)+2) ==>typeof(&a[1][2])==>int* 数值上: X + 24
*(a+1)+2
==> *(&a[0] + 1) + 2
==> *(&a[1])+2
==> a[1]+2
==> &a[1][0] + 2 ==> &a[1][2]
*(a[1]+2) 代表 a[1][2]这个元素 输出:a[1][2]元素的值
*(a[1]+2)
==> *(&a[1][0] + 2)
==> *(&a[1][2])
==> a[1][2]
*(*(a+1)+2) 代表 a[1][2]这个元素 输出:a[1][2]元素的值
*(*(a+1)+2)
==> *(*(&a[0]+1)+2)
==> *(*(&a[1])+2)
==> *(a[1]+2)
==> *(&a[1][0]+2)
==> *&a[1][2]
==> a[1][2]
结论
a[N][M] (0 <= i < N, 0 <= j < M) a+i ==> &a[i] *(a+i) ==> a[i] *(a+i)+j ==> a[i]+j ==> &a[i][j] *(*(a+i)+j) ==> a[i][j] a[i] + j ==> &a[i][j] *((a[i])+j) ==> a[i][j]
数组指针和指针数组
数组指针
-
本质上是一个指针,指向的对象是一个数组
int a[4]; // 定义一个指针变量p,保存a的地址 typeof(a) *p; ==> int[4] *p = &a; ==> int(*p)[4] = &a;// 此时 p就是一个数组指针 typeof(p) ==> int[4]* p+1 ==> 加了一个 int[4] *(*p+1) = 100; *(a+1) ==> *(&a[0] + 1) ==>*&a[1] ==> a[1] // *p <==> 代表p所指向的对象 *p <===> a //(*p)[1] = 100;// ==> a[1] = 100 *p <===> *(p+0) <==> p[0] <==> a // (*p)[1] = 100;// ==> p[0][1] = 100 ==> a[1] = 100 ================================ #include <stdio.h> int main() { int a[4] = {1,2,3,4}; // 定义一个指针变量p,保存a的地址 //typeof(a) *p = &a; int (*p)[4] = &a;// typeof(p) ==> int[4]* //(*p)[1] = 100;// 因为p保存的是整个数组a的地址,此时 *p 就是数组名 //(*p)[1] = 100;// a[1] = 100 //p[0][1] = 100;// p指向一块空间, 看作数组名, 里面每个元素都是int[4] //printf("%d\n", sizeof((*p)+1));// //*((*p)+1) = 100; *(p[0]+1) = 100; //*(*p+1) = 100; for(int i = 0; i < 4; i++) printf("%d ", a[i]); printf("\n"); } ================================ #include <stdio.h> int main() { int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; int(*p)[4] = a;// p = &a[0]; //*p <==> *(p+0) <==> a[0] <==> p[0] printf("%d\n", p[0][0]); printf("%d\n", (*(p+2))[2]);// (*(p+2))[2] ==> (*(&a[2]))[2] ==> a[2][3] printf("%d\n", *(p[1]+2));// *(p[1]+2) ==> *(a[1]+2) ==> *(&a[1][0] + 2) ==> a[1][2] printf("%d\n", *(*(p+2)+2)); } =========================================== #include <stdio.h> int main() { int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; //定义一个指针变量p,保存a的地址 int (*p)[3][4] = &a;// int[4][3]* printf("sizeof(*p) = %ld\n", sizeof(*p)); printf("sizeof((*p)[0]) = %ld\n", sizeof((*p)[0])); }
指针数组
-
本质上是一个数组:里面的元素类型都是指针类型
int a[4] = {1,2,3,4}; int *p[4];// p 就是一个数组, 数组中有4个int*的元素 typeof(p) ==> int*[4] sizeof(p) ==> 32 p[0] = a;// p[0] = &a[0] *p[0] <==> a[0] *p <==> *&p[0] <==> p[0] **p <==> a[0]
练习
- 最后附上一个leedcode上练习的数组题
给你一个整型数组 nums
,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
示例 1:
输入:nums = [1,2,3] 输出:6
示例 2:
输入:nums = [1,2,3,4] 输出:24
示例 3:
输入:nums = [-1,-2,-3] 输出:-6
提示:
3 <= nums.length <= 104
-1000 <= nums[i] <= 1000
int maximumProduct(int* nums, int numsSize) {
int a,b,c;
int count=0;
int mul=1;
int a_fu=INT_MAX;
int b_fu=INT_MAX;
int c_fu=INT_MAX;
a=b=c=INT_MIN;
for(int i=0;i<numsSize;i++)
{
if(nums[i]<0)
count++;
if(nums[i]>=a)
{
c=b;
b=a;
a=nums[i];
}
else if(nums[i]>=b&&nums[i]<=a)
{
c=b;
b=nums[i];
}
else if(nums[i]>=c&&nums[i]<=b)
{
c=nums[i];
}
}
for(int i=0;i<numsSize;i++)
{
if(nums[i]<0&&nums[i]<=a_fu)
{
c_fu==b_fu;
b_fu=a_fu;
a_fu=nums[i];
}
else if(nums[i]<0&&nums[i]>a_fu&&nums[i]<=b_fu)
{
c_fu=b_fu;
b_fu=nums[i];
}
else if(nums[i]<0&&nums[i]>b_fu&&nums[i]<=c_fu)
c_fu=nums[i];
}
if(b_fu!=INT_MAX&&count!=numsSize)
{
if(a*a_fu*b_fu>a*b*c)
mul=a*a_fu*b_fu;
else mul=a*b*c;
}
else
mul=a*b*c;
return mul;
}
代码还是有些许的冗长,还有待提升~~~