@TOC
前言
接受了老师的建议 会用代码块写代码了
不弄那些花里胡哨的了
一、整形数组
**除了 sizeof(数组名) 数组名代表整个数组的大小
&数组名 数组名代表整个数组的大小 取出的是整个数组的地址
其他的数组名代表首元素地址
地址可以看作指针 在32位下指针为4个字节
在 64位下指针为8个字节**
#include<stdio.h> int main() { int a[]={1,2,3,4}; printf("%d\n",sizeof(a)); printf("%d\n",sizeof(a+0)); printf("%d\n",sizeof(*a)); printf("%d\n",sizeof(a+1)); printf("%d\n",sizeof(a[1])); }
- a 代表sizeof(数组名)整个数组的大小 即4*4=16
- a+0 a作为数组名没有单独放在sizeof内部 也没有取地址
数组名代表首元素地址 即1的地址 即4/8- *a a作为数组名没有单独放在sizeof内部 也没有取地址
数组名代表首元素地址 *a为第一个元素 即4- a+1 a作为数组名没有单独放在sizeof内部也没有取地址
数组名代表首元素地址 a+1代表第二个元素的地址 即4/8- a[1] 等价于 *(a+1) a作为数组名没有单独放在sizeof内部
也没有取地址 数组名代表首元素地址 *(a+1)为第二个元素
即 4
#include<stdio.h> int main() { int a[]={1,2,3,4}; printf("%d\n",sizeof(&a)); printf("%d\n",sizeof(*&a)); printf("%d\n",sizeof(&a+1)); printf("%d\n",sizeof(&a[0])); printf(‘%d\n",sizoef(&a[0]+1)); }
- &a a作为数组名 取地址 数组名作为整个数组的大小
&a 取出的是整个数组的地址 即4/8- *&a a作为数组名 取地址 数组名作为整个数组的大小
*&a代表整个数组的元素 即16- &a+1 a作为数组名 取地址 数组名作为整个数组的大小
&a+1代表跳过整个数组后下一块空间的地址
但依旧是地址 即 4/8
在这里插入图片描述
- &a[0] a[0]等价于(a+0) 即 &(a+0) a作为数组名没有单独放在sizeof 内部也没有取地址 数组名代表首元素地址 即4/8
- &a[0]+1 a[0]等价于 (a+0) 即 &(a+0) +1
a作为数组名没有单独放在sizeof 内部也没有取地址 数组名 代表首元素地址 首元素地址加1为 第二个元素的地址 即4/8
# 二、字符数组
#include<stdio.h> int main() { char arr[]={'a','b','c','d','e','f'}; printf("%d\n",sizeof(arr)); printf("%d\n",sizeof(arr+0)); printf("%d\n",sizeof(*arr)); printf("%d\n",sizeof(arr[1])); printf("%d\n",sizeof(&arr)); printf("%d\n",sizeof(&arr+1)); printf("%d\n",sizeof(&arr[0]+1)); return 0; }
- arr 代表sizeof(数组名)整个数组的大小 即1*6=6
- arr+0 arr作为数组名没有单独放在sizeof内部 也没有取地址
数组名代表首元素地址 即 4/8- *arr 代表 arr作为数组名没有单独放在sizeof内部 也没有取地址
数组名代表首元素地址 *arr为第一个元素 即 1- arr[1]等价于 *(arr+1) arr作为数组名没有单独放在sizeof内部 也没有取 地址 arr+1为第二个元素的地址 *(arr+1)为第二个元素 即1
- &arr arr作为数组名 取地址 数组名作为整个数组的大小
&arr代表整个数组的地址 即4/8- &arr+1 arr作为数组名 取地址 数组名作为整个数组的大小
&arr+1代表跳过整个数组后下一块空间的地址- &arr[0]+1 arr[0]等价于 (arr+0) 即 &(arr+0)+1
arr作为数组名没有单独放在sizeof内部 也没有取地址
数组名代表首元素地址 &*可以抵消 第一个元素地址加1为
第二个元素的地址 即 4/8
#include<stdio.h> int main() { char arr[]={'a','b','c','d','e','f'}; printf("%d\n",strlen(arr)); printf("%d\n",strlen(arr+0)); printf("%d\n",strlen(*arr)); printf("%d\n",strlen(arr[1])); printf("%d\n",strlen(&arr)); printf("%d\n",strlen(&arr+1)); printf("%d\n",strlen(&arr[0]+1)); return 0; }
strlen 从当前地址 向后找到'\0’停止
- arr作为数组名没有单独放在sizeof内部 也没有取地址
数组名代表首元素地址 从‘a'开始 没有'\0'不知道什么时候找到
即 随机值- arr+0 arr作为数组名没有单独放在sizeof内部 也没有取地址
数组名代表首元素地址 从‘a'开始 没有'\0'不知道什么时候找到
即随机值- *arr arr作为数组名没有单独放在sizeof内部 也没有取地址
数组名代表首元素地址 *arr即第一个元素 strlen是从当前地址开始
即 报错- arr[1]等价于 *(arr+1) arr作为数组名没有单独放在sizeof内部 也没有 取地址 数组名代表首元素地址 *(arr+1)为第二个元素
即报错- &arr arr作为数组名 取地址 数组名作为整个数组
&arr 取的是整个数组的地址 应用数组指针char(*)[]
而在strlen函数中是由 字符指针接受的 传过来应为第一个元素的地址
即 随机值- &arr arr作为数组名 取地址 数组名作为整个数组
&arr 取的是整个数组的地址
&arr+1为跳过整个数组的下一块空间的地址
即随机值-6
>7. &arr[0]+1 arr[0]等价于*(arr+0) 即&*(arr+0)+1 arr作为数组名没有单独放在sizeof内部 也没有取地址 数组名代表首元素地址 即为第二个元素的地址 不知道什么时候找到 '\0' 即随机值-1
#include<stdio.h> int main() { char arr[]="abcdef"; printf("%d\n",strlen(arr)); printf("%d\n",strlen(arr+0)); printf("%d\n",strlen(*arr)); printf("%d\n",strlen(arr[1])); printf("%d\n",strlen(&arr)); printf("%d\n",strlen(&arr+1)); printf("%d\n",strlen(&arr[0]+1)); return 0; }
a b c d e f \0
strlen从当前地址开始 到'\0'
1. arr作为数组名没有单独放在sizeof内部 也没有取地址
数组名代表首元素地址 即 6
>2. arr作为数组名没有单独放在sizeof内部 也没有取地址 数组名代表首元素地址 即6 >3.*arr . arr作为数组名没有单独放在sizeof内部 也没有取地址 数组名代表首元素地址 *arr 为第一个元素 即报错 >4.arr[1] 等价于 *(arr+1) . arr作为数组名没有单独放在sizeof内部 也没有取地址 数组名代表首元素地址 *(arr+1)为第二个元素 即报错 >5.&arr arr作为数组名 取地址 数组名代表整个数组 &arr代表整个数组的地址 从首元素地址开始 即 6 >6.&arr+1 .&arr arr作为数组名 取地址 数组名代表整个数组 &arr代表整个数组的地址 &arr+1表示跳过整个整个数组的下一块空间的地址 即随机值 >7. &arr[0]+1 arr[0]等价于 *(arr+0) 即 &*(arr+0)+1 &*可以抵消 arr作为数组名没有单独放在sizeof内部 也没有取地址 数组名代表首元素地址 &arr[0]+1为 第二个元素的地址 即5
#include<stdio.h> int main() { char*p="abcdef"; printf("%d\n",strlen(p)); printf("%d\n",strlen(p+1)); printf("%d\n",strlen(*p); printf("%d\n",strlen(p[0])); printf("%d\n",strlen(&p)); printf("%d\n",strlen(&p+1)); printf("%d\n",strlen(&p[0]+1)); return 0; }
p为一个字符指针 接收a的地址
- p 从a的地址到'\0' 即6
- p+1 从b的地址开始 即 5
- *p 即为a本身 strlen 从地址开始 即报错
- p[0] 等价于 *(p+0) 为a本身 即报错
- &p p本身为一个字符指针 指针的地址为二级指针
也是个地址 但不知道'\0'的位置 即随机值
在这里插入图片描述
6.&p+1 p本身为一个字符指针 指针的地址为二级指针
+1指向p本身末尾位置 但也是个地址
即随机值
在这里插入图片描述
7.&p[0]+1 p[0]等价于 *(p+0)
即& *(p+0)+1 &*可以抵消 即第二个元素的地址
即 5
三、二维数组
#include<stdio.h> int main() { int a[3][4]={0}; printf("%d\n",sizeof(a)); printf("%d\n",sizeof(a[0][0])); printf("%d\n",sizoef(a[0])); printf("%d\n,sizoef(a[0]+1)); printf("%d\n",sizeof(*(a[0]+1))); printf("%d\n",sizeof(a+1)); printf("%d\n",sizeof(*(a+1)); printf("%d\n",sizoef(&a[0]+1)); printf("%d\n",sizeof(*(&a[0]+1))); printf("%d\n",sizeof(*a)); printf("%d\n",sizeof(a[3)); return 0; }
- sizeof(数组名)为整个二维数组的大小 即 48
- a[0][0] 代表第一行第一个元素 即 4
- a[0]作为第一行的数组名 sizeof(数组名)为整个第一行的大小
即 4*4=16- a[0]+1 a[0]作为第一行的数组名 数组名没有单独放在sizeof内部
也没有取地址 数组名表示首元素地址 即第一行第一个的地址
a[0]+1代表第一行第二个的地址 即4/8- *(a[0]+1) a[0]作为第一行的数组名 数组名没有单独放在sizeof内部
也没有取地址 数组名表示首元素地址 +1表示第一行第二个元素的地址
解引用表示 第一行第二个元素 即 4- a+1 a作为二维数组的数组名 数组名没有单独放在sizeof内部
也没有取地址 数组名表示首元素地址 二维数组首元素地址为第一行的 地址, +1后为第二行的地址 即4/8- *(a+1) 即为第二行元素 即4 * 4=16
- &a[0]+1 a[0] 作为第一行的数组名 取地址后 数组名代表 第一行元素
&a[0]代表取整个第一行的元素的地址 , +1 后第二行的地址
即4/8- *(&a[0])+1 即第二行的元素 即 4 * 4=16
- *a a作为二维数组的数组名 数组名没有单独放在sizeof内部
也没有取地址 数组名表示首元素地址 二维数组首元素地址为第一行的 地址, 即第一行的元素 即 4 *4=16- sizeof内部不实际参与运算
a[3] 代表第四行的元素 即 4*4=16