#include
int main()
{
int a[] = {1,2,3,4};
printf("%d\n", sizeof(a));//16
//sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节
printf("%d\n", sizeof(a+0));// 4/8
//a不是单独放在sizeof内部,也没有取地址,所以a就是首元素的地址,故a+0也是首元素的地址
//地址的大小为4/8个字节
printf("%d\n", sizeof(*a));//4
//*a中的a是数组中首元素的地址,*a就是对首元素的地址解引用,找到的就是首元素
//首元素的大小为4个字节
printf("%d\n", sizeof(a+1));// 4/8
//这里的a是数组首元素的地址,a+1为第二个元素的地址
//sizeof(a+1)就是地址的大小
printf("%d\n", sizeof(a[1])); //4
// sizeof(*(a+1));
//计算的是第二个元素的大小
printf("%d\n", sizeof(&a)); // 4/8
//&a取出的是整个数组的地址,计算的也是地址
printf("%d\n", sizeof(*&a));//16
//&a---->int(*)[4]
//&a拿到的是整个数组的地址,解引用后获得整个数组的元素
//故求的是整个数组所占内存的大小
printf("%d\n", sizeof(&a+1));// 4/8
//&a拿到的是整个数组的地址,+1后跳过一整个数组的大小(16个字节)
//&a+1也是地址,故为4/8个字节
printf("%d\n", sizeof(&a[0]));// 4/8
// sizeof(&*(a+0))
//a[0]是第一个数组元素,取地址后得到的是第一个元素的地址
printf("%d\n", sizeof(&a[0]+1)); // 4/8
//&a[0]是数组首元素的地址,+1后得到第二个元素的地址
return 0;
}
#include
int main()
{
char arr[] = { 'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//6
//sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节
printf("%d\n", sizeof(arr+0));// 4/8
//arr+0是数组首元素的地址
printf("%d\n", sizeof(*arr));//1
//*arr是数组的首元素,大小为1字节
printf("%d\n", sizeof(arr[1]));//1
// sizeof(*(arr+1))
//为数组的第二个元素
printf("%d\n", sizeof(&arr));// 4/8
//&arr取出的是整个数组的地址,是地址就是4/8个字节
printf("%d\n", sizeof(&arr+1)); // 4/8
//&arr+1也是地址,故为4/8个字节
printf("%d\n", sizeof(&arr[0]+1));// 4/8
//&arr[0]是数组首元素的地址,+1后得到第二个元素的地址
return 0;
}
#include
#include
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));//随机值
//strlen函数从指定地址进入后,需要遇到\0才会停止计数
//字符数组中没有\0,故其会一直向后读取,直到在内存中遇到\0
printf("%d\n", strlen(arr + 0));//随机值
//arr+0表示的是数组的首元素地址
printf("%d\n", strlen(*arr));//错误
//*arr表示的是数组的首元素'a'
//strlen需要的参数为指针类型,报错
printf("%d\n", strlen(arr[1]));//错误
//arr[1]表示数组的首元素
//strlen需要的参数为指针类型,报错
printf("%d\n", strlen(&arr));//随机值
//&arr取出的是整个数组的地址,而整个数组地址的起始点为首元素地址
printf("%d\n", strlen(&arr + 1));//随机值-6
//&arr拿到的是整个数组的地址,+1后跳过一整个数组的大小(6个字节)
printf("%d\n", strlen(&arr[0] + 1));//随机值-1
//&arr[0]是数组首元素的地址,+1后得到第二个元素的地址
return 0;
}
#include
int main()
{
char arr[] = "abcdef";
//[a b c d e f \0]
printf("%d\n", sizeof(arr)); //7
//arr在sizeof函数中表示全部元素,\0也会计数
printf("%d\n", sizeof(arr+0)); // 4/8
//第一个元素的地址
printf("%d\n", sizeof(*arr)); //1
//第一个元素
printf("%d\n", sizeof(arr[1])); //1
//第二个元素
printf("%d\n", sizeof(&arr)); // 4/8
//整个字符串的地址
printf("%d\n", sizeof(&arr+1));// 4/8
//从首元素地址跳过一整个字符串长度的地址
printf("%d\n", sizeof(&arr[0]+1)); // 4/8
//第二个元素的地址
return 0;
}
#include
#include
int main()
{
char arr[] = "abcdef";
//[a b c d e f \0]
printf("%d\n", strlen(arr)); //6
//首元素地址
printf("%d\n", strlen(arr+0)); //6
//首元素地址
printf("%d\n", strlen(*arr)); //错误
//strlen需要的参数为指针类型,报错
printf("%d\n", strlen(arr[1])); //错误
//strlen需要的参数为指针类型,报错
printf("%d\n", strlen(&arr)); //6
//首元素地址
printf("%d\n", strlen(&arr+1)); //随机值
//首元素地址跳过一整个字符串长度的地址
printf("%d\n", strlen(&arr[0]+1)); //5
//第二个元素的地址
return 0;
}
#include
int main()
{
char* p = "abcdef";
printf("%d\n", sizeof(p));// 4/8
//p是字符串的首元素地址
printf("%d\n", sizeof(p+1));// 4/8
//第二个元素的地址
printf("%d\n", sizeof(*p));// 1
//字符串首元素
printf("%d\n", sizeof(p[0]));// 1
//字符串首元素
printf("%d\n", sizeof(&p));// 4/8
//指向首元素地址的二级指针
printf("%d\n", sizeof(&p+1));// 4/8
//指向第二个元素地址的二级指针
printf("%d\n", sizeof(&p[0]+1));// 4/8
// sizeof(&(*(p+0))+1)
//第二个元素的地址
return 0;
}
#include
#include
int main()
{
char* p = "abcdef";
printf("%d\n", strlen(p)); //6
//第一个元素的地址
printf("%d\n", strlen(p+1));//5
//第二个元素的地址
printf("%d\n", strlen(*p));//报错
//第一个元素,与strlen所需的参数不同
printf("%d\n", strlen(p[0]));//报错
//第一个元素,与strlen所需的参数不同
printf("%d\n", strlen(&p));//随机值1
//整个字符串的地址
printf("%d\n", strlen(&p+1));//随机值2
//首个元素地址+整个字符串长度的地址
printf("%d\n", strlen(&p[0]+1)); //5
//第二个元素的地址
return 0;
}
5.二维整形数组
(1) sizeof()对二维整形数组的应用
#include
int main()
{
int a[3][4] = {0};
printf("%d\n", sizeof(a));//48
//a在sizeof中表示整个数组元素所占的内存大小
printf("%d\n", sizeof(a[0][0]));//4
//第一个元素
printf("%d\n", sizeof(a[0]));//16
//第一行元素
printf("%d\n", sizeof(a[0]+1));// 4/8
//第一行第二个元素的地址
printf("%d\n", sizeof(*(a[0]+1)));//4
//第一行第二个元素
printf("%d\n", sizeof(a+1));// 4/8
//第二行元素的地址
printf("%d\n", sizeof(*(a+1)));//16
//第一行元素
printf("%d\n", sizeof(&a[0]+1));// 4/8
//第二行元素的地址
printf("%d\n", sizeof(*(&a[0]+1)));//16
//第二行元素
printf("%d\n", sizeof(*a));//16
//第一行元素
printf("%d\n", sizeof(a[3]));//16
//第三行元素
return 0;
}
#include
int main()
{
int a[5] = {1,2,3,4,5};
int* ptr = (int*)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
return 0;
}
答案:2,5
#include
int main()
{
int a[5] = {1,2,3,4,5};
int* ptr = (int*)(&a+1);
//ptr为首元素地址跳过整个数组
printf("%d,%d",*(a+1),*(ptr-1));//2,5
return 0;
}
#include
//已知结构体Test类型的变量大小为20个字节
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p=(struct Test*)0x100000;
int main()
{
printf("%p\n",p+0x1); //0x100014
//struct Test类型加一增加20个字节
printf("%p\n", (unsigned long)p + 0x1);//0x100001
//unsigned long类型加一增加1个字节
printf("%p\n", (unsigned int*)p + 0x1);//0x100004
//unsigned int*类型加一增加4个字节
return 0;
}
答案: 0000000000100020 ,0000000000100001 , 0000000000100004
#include
//已知结构体Test类型的变量大小为20个字节
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p=(struct Test*)0x100000;
int main()
{
printf("%p\n",p+0x1); //0x100014
//struct Test类型加一增加20个字节
printf("%p\n", (unsigned long)p + 0x1);//0x100001
//unsigned long类型加一增加1个字节
printf("%p\n", (unsigned int*)p + 0x1);//0x100004
//unsigned int*类型加一增加4个字节
return 0;
}
#include
int main()
{
int a[4] = {1,2,3,4};
int* ptr1 = (int*)(&a + 1);
int* ptr2 = (int*)((int)a + 1);
printf("%x,%x",ptr1[-1],*ptr2);
return 0;
}
答案:4,20000
#include
int main()
{
int a[4] = {1,2,3,4};
int* ptr1 = (int*)(&a + 1);
//ptr1为数组首元素地址跳过一整个数组的地址
int* ptr2 = (int*)((int)a + 1);
//(int)a+1增加一个字节,(int*)((int)a + 1)为首元素地址向后一个字节
//00 00 00 01 | 00 00 00 02 | 00 00 00 03 | 00 00 00 04——数组中元素地址
//01 00 00 00 | 02 00 00 00 | 03 00 00 00 | 04 00 00 00——在内存中存储(小端存储)
// | |
// ptr2 ptr1
printf("%x,%x",ptr1[-1],*ptr2);
//以十六进制输出时,ptr1[-1]为后退四个字节,然后读取四个字节输出——00 00 00 04
//*ptr2为读取四个字节然后输出——02 00 00 00
return 0;
}
#include
int main()
{
int a[3][2] = {(0,1),(2,3),(4,5)};
int* p;
p = a[0];
printf("%d",p[0]);
return 0;
}
答案:1
#include
int main()
{
int a[3][2] = {(0,1),(2,3),(4,5)};//逗号表达式,读取的值为后面的数
int* p;
p = a[0];
//p为第一行的元素
printf("%d",p[0]);
//p[0]是第一行的第一个元素
return 0;
}
#include
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf("%p,%d\n",&p[4][2]-&a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
答案: -4,FFFFFFFC
#include
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf("%p,%d\n",&p[4][2]-&a[4][2], &p[4][2] - &a[4][2]);
//&p[4][2]-&a[4][2]=(-4)
//10000000 00000000 00000000 00000100——(-4)原码
//11111111 11111111 11111111 11111011——反码
//11111111 11111111 11111111 11111100——补码
//FF FF FF FC——十六进制
//按地址输出时把补码当做地址输出
return 0;
}
#include
int main()
{
int aa[2][5] = {1,2,3,4,5,6,7,8,9,10};
int* ptr1 = (int*)(&aa+1);
int* ptr2 = (int*)(*(aa + 1));
printf("%d,%d",*(ptr1-1),*(ptr2-1));
return 0;
}
答案: 10,5
#include
int main()
{
int aa[2][5] = {1,2,3,4,5,6,7,8,9,10};
int* ptr1 = (int*)(&aa+1);
//ptr1为首元素地址跳过整个数组后的地址
int* ptr2 = (int*)(*(aa + 1));
// (int*)aa[1]
printf("%d,%d",*(ptr1-1),*(ptr2-1)); //10,5
//*(ptr1-1)—>*(a[2]-1)—>a[1][4]
//*(ptr2-1))—>*(aa[1]-1)—>aa[0][4]
return 0;
}
#include
int main()
{
char* a[] = {"work","at","alibaba"};
char** pa = a;
pa++;
printf("%s\n",*pa);
return 0;
}
答案:at
#include
int main()
{
char* a[] = {"work","at","alibaba"};
char** pa = a;
//pa为字符串首元素("work")的地址
pa++;
//++后pa指向"at"
printf("%s\n",*pa);
return 0;
}
#include
int main()
{
char* c[] = {"ENTER","NEW","POINT","FIRST"};
char** cp[] = {c+3,c+2,c+1,c};
char*** cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *--*++cpp+3);
printf("%s\n", *cpp[-2]+3);
printf("%s\n", cpp[-1][-1]+1);
return 0;
}
答案: POINT,ER,ST,EW
#include
int main()
{
char* c[] = {"ENTER","NEW","POINT","FIRST"};
char** cp[] = {c+3,c+2,c+1,c};
char*** cpp = cp;
//cpp为c+3的地址
printf("%s\n", **++cpp);//POINT
//++cpp—>c+2的地址
// **++cpp—>"POINT"的首元素地址printf("%s\n", *--*++cpp+3);//ER
//cpp为c+2的地址
//++cpp—>c+1的地址
//--*++cpp—>c+1-1—>c
//*--*++cpp—>"ENTER"的首元素地址
//*--*++cpp+3—>"ENTER"第四个元素的地址printf("%s\n", *cpp[-2]+3);//ST
//cpp为c+1的地址
//cpp[-2]—>*(cpp-2)—>元素c+3—>"FIRST"的地址
//*cpp[-2]+3—>*(cpp[-2]+3)—>"FIRST"的第四个元素的地址printf("%s\n", cpp[-1][-1]+1);//EW
//cpp为c+1的地址
//cpp[-1]—>*(cpp-1)—>元素c+2—>"POINT"的地址
//cpp[-1][-1]—>*(cpp[-1]-1)—>"NEW"的地址
//cpp[-1][-1]+1—>"NEW"第二个元素的地址
return 0;
}