#include
#include
#include
void func(char **p, int num)
{
for (int i = 0; i < num; i++) {
// printf("%s\n", p[i]);
// printf("%s\n", *(p+i));
printf("%s\n", *p++);
}
}
int main(int argc, char *argv[], char** env)
{
#if 0
struct student
{
int a;
char b;
};
struct student *stud;
struct student stu;
stu.a = 222;
*stud = stu;
int arr[5] = {
10,20,30,40,50};
int str[5] = {
100,200,300,400,500};
/*数组指针指向数组首元素地址的指针,相当于一个二级指针,这个指针不可移动,它的长度和二维数组的列相同*/
int(*p)[5] = &arr;//因为数组指针相当于二级指针,所以这里必须传入一维数组的地址
printf("arr[1]=%d\n", *(p[0]+1));//p[0][1]
int a = 1000;
/*指针数组是一个数组,里面存储的是指向变量的指针,变量是指针数组类型的就行,它的长度的二维数组的行相同*/
int *q[5] = {
arr, str, &a, &stu.a};
*(q[1]+2) = 1;
printf("str[1]=%d\n", *(q[1]+1));
*q[2] = 2000;
printf("a=%d\n", *(q[2]+0));
printf("arr[1]=%d\n", q[0][1]);
printf("stu.a=%d,stud->a=%d\n", q[3][0], *q[3]);
int num[2][5] = {
{
111,222,333,444,555},{
666,777,888,999,1111}};
/*第一种方法传入的是数组各元素的地址*/
int(*ptr)[2][5] = #
printf("num[1][4]=%d\n", ptr[0][1][4]);//第一个必须是0,第二个控制着行,第三个控制着列
printf("num[0][3]=%d\n", *(ptr[0][0]+3));//第一个必须是0,第二个控制着行,+控制着列
/*第二种方法传入的数组的各元素*/
int(*ptr1)[5] = num;
printf("num[0][3]=%d\n",ptr1[0][3]);
printf("num[1][2]=%d\n", *(ptr1[1]+2));
#endif
#if 0
char str1[10] = "hello";
char str2[10] = "world";
char str3[10] = "windows";
char str4[10] = "linux";
char str5[2][6] = {
"12345","abcde"};
printf("%u\n", sizeof (*str5) / sizeof (**str5));//求列长
char x = 'a';
char(*ptr)[6] = str5;
printf("str5[0]=%s,str5[1]=%s\n", ptr[0],*(ptr+1));//*(ptr[0]+1)程序报错,(ptr[0]+1)=2345
char(*p)[10] = &str1;
printf("str1[10]=%s\n", *p);
char *q[10] = {
str1, str2, str3, str4, &x};
printf("str2[10]=%s, x=%c\n", q[1], *q[4]);
#endif
#if 0
/*二维数组也是线性存储的,通过数组指针也可以实现对一维数组的二维访问方式*/
int arr[12] = {
1,2,3,4,5,6,7,8,9,10,11,12};
int(*p)[4] = (int(*)[4])arr;
for (int i = 0; i < sizeof (arr) / sizeof (int[4]); i++) {
for (int j = 0; j < 4; j++) {
printf("%d\t", p[i][j]);
}
putchar(10);
}
#endif
#if 0
/*a是一个二维数组,&a[4][2]就是取这个元素的地址,因为a是5个元素一行,所以&a[4][2]也就是第5行的第3个元素,
* 而p是4个元素一行,&p[4][2]也就没&a[4][2]的地址高,而它们之间正好间隔4个元素,结果就是-4*/
int a[5][5];
int (*p)[4] = a;
printf("%d\n", &p[4][2] - &a[4][2]);
#endif
#if 0
int a[10] = {
0,1,2,3,4,5,6,7,8,9};
printf("&a[9]=%p\t &a[4]=%p\n", &a[9], &a[4]);
printf("&a[9]=%d\t &a[4]=%d\n", &a[9], &a[4]);
printf("(int)&a[9]=%p\t (int)&a[4]=%p\n", (int)&a[9], (int)&a[4]);
printf("(int)&a[9]=%d\t (int)&a[4]=%d\n", (int)&a[9], (int)&a[4]);
printf("&a[9] - &a[4]=%d\n", &a[9]-&a[4]);//5
printf("(int)&a[9] - (int)&a[4]=%d\n", (int)&a[9]-(int)&a[4]);//20
printf("(int)&a[6] - (int)&a[0]=%d\n", (int)&a[6] - (int)&a[3]);//12
#endif
#if 0
int a[5] = {
1,2,3,4,5};
/*a在内存中的布局是01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00,小端是这样,大端反过来*/
int *p = (int*)(&a + 1);
int *q = (int*)((int)a + 1);
printf("p=%#p\t q=%#p\n", p[-1], *q);
/*p[-1] = *(p-1),(int*)((int)a+1)a被强制转换成了int型,所以a+1=2,然后2再次被强制转换成了(int*),
那么就往前移动了4个字节,也就是一个int的距离,此时q指向了02,又因为q的类型是int*,所以取q的值时,连带
02后面的6个0就一起被取了出来,所以显示是0x02000000*/
#endif
/*二级指针和一维数组、二维数组都没关系,和指针数组有关系*/
#if 1
/*pa的本质还是数组,pa里面每个元素都是char*的,对pa[0]取地址就是char**了*/
char *pa[] = {
"Orcale", "IBM", "Facebook", "Tencent", "GOOGLE", "HuaWei", NULL};//在指针数组的最后加一个NULL
// func(pa, sizeof (pa)/sizeof (pa[0]));
char **q = pa;
while (*q) {
printf("pa=%s\n", *q++);
}
#endif
#if 0
char a[] = "china";
char *p = a;
int i = 0;
while (*p) {
printf("a[%d]=%c\n", i, *p++);
i++;
}
#endif
#if 1
// for (int i = 0; i < argc; i++) {
// printf("%s\n", argv[i]);
// }
// while (*argv) {
// printf("%s, %d\n", *argv++);
// }
// while (*env) {
// printf("%s\n", *env++);
// }
// argv[0] = "123";
// argv[1] = "abc";
// printf("argv[0]=%s\nargv[1]=%s\n", argv[0], argv[1]);
#endif
return 0;
}
/*一维数组名等价于1级指针,对一维数组名取地址就等价于数组指针,并不是二级指针*/
指针数组和数组指针,C语言一定要掌握的知识点。