数组
数组类型
typedef int (MyArray)[5];
MyArray a; //int a[5]
关于步长问题:
int a[3];
a
代表数组首元素地址
&a
代表整个数组的地址
a+1
步长为sizeof(int)
&a+1
步长为sizeof(int)*3
数组指针类型
即指向数组的指针
/*
第一种方法
*/
typedef int (MyArray)[5];
MyArray a;
MyArray *pa = NULL;
pa = &a;
(*pa)[0] = 1;
/*
第二种方法
*/
typedef int (*MyPointer)[5];
/*
第三种方法
*/
int (*pMyArray)[5];
多维数组
多维数组名的本质是数组指针。它的步长是每行的长度。
#include<stdio.h>
int main(int argc, char *argv[])
{
int a[3][5];
void *p1 = NULL,*p2 = NULL;
p1 = a;
p2 = a+1;
printf("a: %p\n",a);
printf("a+1:%p\n",a+1 );
printf("(a+1)-a:%d\n",p2-p1);
p1 = &a;
p2 = &a+1;
printf("&a: %p\n",&a);
printf("&a+1:%p\n",&a+1 );
printf("(&a+1)-&a:%d\n",p2-p1);
return 0;
}
/*
a: 0060FEE0
a+1:0060FEF4
(a+1)-a:20
&a: 0060FEE0
&a+1:0060FF1C
(&a+1)-&a:60
*/
二维数组表示 | 解释 |
---|---|
a | 第1行的地址 |
a+1 | 第2行的地址 |
*(a+1) + 1 | 第2行第2列元素的地址,&a[0][1] |
*(*(a+1) + 1) | 第2行第2列元素的值 |
推演:
a[i] == *(a+i)
a[i][j] == a[0+i][j] == *(a+i)[j] == *( (a+i) + j )
多维数组空间
线性空间
#include<stdio.h>
print(int *a,int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%d\n",*(a+i));
}
}
int main(int argc, char *argv[])
{
int a[2][3];
int i,j;
int val = 1;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
a[i][j] = val++;
}
}
print((int*)a,6);
return 0;
}
多维数组传参
//因为a是数组指针,所以可作如下退化。
func(char a[5][10]);
func(char a[][10]);
func(char (*a)[10]);
数组参数 | 等效指针参数 |
---|---|
char a[10] | char *a |
char *a[10] | char **a |
char a[5][10] | char (*a)[10] |
指针数组
两种用法:菜单,命令行。
char *table[] = {
"option 1",
"option 2",
"option 3",
'\0' //也可以是NULL,或0.
};
int i;
for(i = 0; table[i] != NULL; i++)
{
printf("%s\n",table[i]);
}
自我结束能力
\0
,0
,NULL
都可以表示结束。
结构体
定义结构体名:固定大小内存块的别名.
定义方法
struct Person{};
typedef struct Person{} Person;
struct Person{
char name[10];
int age;
} p1 = {"foobar",1},p2;
p2.age = 2;
struct {} s1,s2; //匿名结构体
点操作符.
是寻址操作,计算变量相对于结构体变量的偏移量. 该寻址操作在cpu中,不是内存中,后续操作(如赋值)在内存中。指针操作->
同理。
结构体直接等号赋值,要注意成员变量指针浅拷贝问题。
结构体本质是固定大小内存的别名。结构体中嵌套自己,无法确定大小,所以编译失败。
成员偏移量
结构体定义时,就确定了内存布局。
#include<stdio.h>
#include<string.h>
struct Person{
char name[10];
int age;
};
int main(int argc, char *argv[])
{
printf("age offset:%d\n",(int)&( ((struct Person *)0)->age) );
{
struct Person *p = NULL;
printf("age offset:%d\n",&(p->age));
}
{
struct Person s;
struct Person *p = &s;
printf("age offset:%d\n",(int)&(p->age) - (int)p);
}
return 0;
}
/*
age offset:12
age offset:12
age offset:12
*/