第一:数组名

一般情况下,数组名就是数组首元素的地址,但是有以下两种情况除外。    1. 数组名单独作为sizeof函数的参数,如sizeof(数组名); 表示的是整个数组所占字节大小。    2. 对数组名做取地址操作,即:&数组名; 代表的是整个数组。即整个数组的地址,其+1操作是跨过整个数组长度大小。

第二:sizeof()库函数在以为整型数组中的应用

int main(){    // 一维整型数组的用sizeof函数计算所占字节大小    int arr[] = { 1,2,4,8,16 };    printf("%d ", sizeof(arr));     // 20    整个数组所占字节大小:4 * 5 = 20    printf("%d ", sizeof(arr + 0)); // 4 | 8 首元素的地址,即地址所占字节:固定    printf("%d ", sizeof(*arr));    // 4     首元素所占字节大小,即int | 1所占字节大小:4    printf("%d ", sizeof(arr + 1)); // 4 | 8 第二个元素的地址所占字节大小:是固定的    printf("%d ", sizeof(arr[1]));  // 4     第二个元素所占字节大小,即int | 2所占字节大小:4    printf("%d ", sizeof(&arr));    // 4 | 8 数组的地址所占字节大小:固定大小,该地址+1是跳过整个数组    printf("%d ", sizeof(*&arr));   // 20    整个数组所占字节大小(*&arr等同于a),即&arr是得到整个数组的地址,对其解引用得到的是整个数组,故为4 * 5 = 20;    printf("%d ", sizeof(&arr + 1));// 4 | 8 指向数组最后一个元素后面所在内存地址的大小:固定大小    printf("%d ", sizeof(&arr[0])); // 4 | 8 首元素地址所占字节大小:固定    printf("%d ", sizeof(&arr[0] + 1)); //4|8第二个元素地址所占字节大小:固定    return 0;}

第三:一维字符数组在sizeof()函数中的应用

int main(){    // 一维字符数组的用sizeof函数计算所占字节大小    char str[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g'};    printf("%d ", sizeof(str));     // 7    整个数组所占字节大小:1 * 7 = 7    printf("%d ", sizeof(str + 0)); // 4 | 8 首元素的地址,即地址所占字节:固定    printf("%d ", sizeof(*str));    // 1     首元素所占字节大小,即char | 'a'所占字节大小:1    printf("%d ", sizeof(str + 1)); // 4 | 8 第二个元素的地址所占字节大小:是固定的    printf("%d ", sizeof(str[1]));  // 1     第二个元素所占字节大小,即char | 'b'所占字节大小:1    printf("%d ", sizeof(&str));    // 4 | 8 数组的地址所占字节大小:固定大小,该地址+1是跳过整个数组    printf("%d ", sizeof(*&str));   // 7     整个数组所占字节大小(*&str等同于str),即&str是得到整个数组的地址,对其解引用得到的是整个数组,故为1 * 7 = 7;    printf("%d ", sizeof(&str + 1));// 4 | 8 指向数组最后一个元素后面所在内存地址的大小:固定大小    printf("%d ", sizeof(&str[0])); // 4 | 8 首元素地址所占字节大小:固定    printf("%d ", sizeof(&str[0] + 1)); //4|8第二个元素地址所占字节大小:固定    return 0;}

第四:一维字符数组在strlen中的应用

strlen函数计算字符串长度,其在内存中遇到'\0',则结束计算
strlen的参数为一个地址。

int main(){    char str[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };    printf("%d ", strlen(str));     // 随机值        str为首元素的地址,从该位置向后访问,直到遇到'\0'时,结束    printf("%d ", strlen(str + 0)); // 随机值        str+0也为首元素的地址,从该位置向后访问,直到遇到'\0'时,结束    // printf("%d ", strlen(*str));    // ERROR         传的是‘a’,其ascll为97,即从内存为97的位置开始访问,属于非法访问内存    // 0x538AFF5C (ucrtbased.dll)处(位于 指针进阶.exe 中)引发的异常: 0xC0000005: 读取位置 0x00000061 时发生访问冲突    // printf("%d ", strlen(str[1]));  // ERROR         同上 读取0x00000062时(十进制:98)发生访问冲突    // 0x52BDFF5C (ucrtbased.dll)处(位于 指针进阶.exe 中)引发的异常: 0xC0000005: 读取位置 0x00000062 时发生访问冲突。    printf("%d ", strlen(str + 1)); // 随机值 - 1    从数组的第二个元素所在地址开始向后访问    printf("%d ", strlen(&str));    // 随机值        从数组的地址(和数组首元素地址相同)的位置开始向后访问    printf("%d ", strlen(*&str));   // 随机值       整个数组所占字节大小(*&str等同于str),即&str是得到整个数组的地址,对其解引用得到的是整个数组,从首元素处开始向后访问;    printf("%d ", strlen(&str + 1));// 随机值 - 7    从数组最后一个元素后面所在内存地址开始访问    printf("%d ", strlen(&str[0])); // 随机值        从数组首元素地址处开始向后访问    printf("%d ", strlen(&str[0] + 1)); //随机值 - 1 从数组第二个元素地址处开始向后访问    return 0;}

第五:用常量字符串进行初始化的一维数组关于sizeof的应用

int main(){    // 一维字符数组(用常量字符串进行初始化, 数组中还存放了'\0'),用sizeof来计算所占字节大小    char str[] = "abcdefg";    printf("%d ", sizeof(str));     // 8    整个数组所占字节大小:1 * 8 = 8    printf("%d ", sizeof(str + 0)); // 4 | 8 首元素的地址,即地址所占字节:固定    printf("%d ", sizeof(*str));    // 1     首元素所占字节大小,即char | 'a'所占字节大小:1    printf("%d ", sizeof(str + 1)); // 4 | 8 第二个元素的地址所占字节大小:是固定的    printf("%d ", sizeof(str[1]));  // 1     第二个元素所占字节大小,即char | 'b'所占字节大小:1    printf("%d ", sizeof(&str));    // 4 | 8 数组的地址所占字节大小:固定大小,该地址+1是跳过整个数组    printf("%d ", sizeof(*&str));   // 8     整个数组所占字节大小(*&str等同于str),即&str是得到整个数组的地址,对其解引用得到的是整个数组,故为1 * 8 = 8;    printf("%d ", sizeof(&str + 1));// 4 | 8 指向数组最后一个元素后面所在内存地址的大小:固定大小    printf("%d ", sizeof(&str[0])); // 4 | 8 首元素地址所占字节大小:固定    printf("%d ", sizeof(&str[0] + 1)); //4|8第二个元素地址所占字节大小:固定    return 0;}

第六:用常量字符串进行初始化的一维数组关于strlen的应用

int main(){    // 一维字符数组(用常量字符串进行初始化, 数组中还存放了'\0'),用strlen来计算字符串的大小    char str[] = "abcdefg";    printf("%d ", strlen(str));         // 7      str为首元素的地址,从该位置向后访问,直到遇到'\0'时,结束:7    printf("%d ", strlen(str + 0));     // 7      tr+0也为首元素的地址,从该位置向后访问,直到遇到'\0'时,结束    //printf("%d ", strlen(*str));     // ERROR  传的是‘a’,其ascll为97,即从内存为97的位置开始访问,属于非法访问内存    printf("%d ", strlen(str + 1));     // 6      从数组的第二个元素所在地址开始向后访问    //printf("%d ", strlen(str[1]));      // ERROR  同上 读取0x00000062时(十进制:98)发生访问冲突    printf("%d ", strlen(&str));        // 7      从数组的地址(和数组首元素地址相同)的位置开始向后访问    printf("%d ", strlen(*&str));       // 7      同strlen(str),即&str是得到整个数组的地址,对其解引用得到的是整个数组,故为7    printf("%d ", strlen(&str + 1));    // 随机值 从数组最后一个元素后面所在内存地址开始访问    printf("%d ", strlen(&str[0]));     // 7      从数组首元素地址处开始向后访问    printf("%d ", strlen(&str[0] + 1)); // 6      从数组第二个元素地址处开始向后访问    return 0;}

第七:用常量字符串进行初始化的字符指针关于sizeof的应用

int main(){    // 用字符指针变量接收一个常量字符串(是将该字符串的首字符的地址赋值给字符指针),用sizeof来计算所占字节大小    char *pstr = "abcdefg";    printf("%d ", sizeof(pstr));     // 4 | 8 p是一个指针变量,其存的是地址,故其大小是固定的    printf("%d ", sizeof(pstr + 0)); // 4 | 8 字符串中首元素a的地址,即地址所占字节:固定    printf("%d ", sizeof(*pstr));    // 1     字符串首元素a所占字节大小,即char | 'a'所占字节大小:1    printf("%d ", sizeof(pstr + 1)); // 4 | 8 字符串中第二个元素b的地址所占字节大小:是固定的    printf("%d ", sizeof(pstr[1]));  // 1     字符串第二个元素b所占字节大小,即char | 'b'所占字节大小:1    printf("%d ", sizeof(&pstr));    // 4 | 8 指针变量pstr的地址,是固定大小的。    printf("%d ", sizeof(*&pstr));   // 4 | 8 等同于sizeof(pstr)          printf("%d ", sizeof(&pstr + 1));// 4 | 8 pstr的地址的下一个地址,是固定的    printf("%d ", sizeof(&pstr[0])); // 4 | 8 首元素地址所占字节大小:固定     printf("%d ", sizeof(&pstr[0] + 1)); //4|8字符串中第二个元素b地址所占字节大小:固定     return 0;}

第八:用常量字符串进行初始化的字符指针关于strlen的应用

int main(){    // 用字符指针变量接收一个常量字符串(是将该字符串的首字符的地址赋值给字符指针),用strlen来计算所占字节大小    char* pstr = "abcdefg";    printf("%d ", strlen(pstr));         // 7      pstr为首元素的地址,从该位置向后访问,直到遇到'\0'时,结束:7    printf("%d ", strlen(pstr + 0));     // 7      pstr+0也为首元素的地址,从该位置向后访问,直到遇到'\0'时,结束    //printf("%d ", strlen(*pstr));     // ERROR  传的是‘a’,其ascll为97,即从内存为97的位置开始访问,属于非法访问内存    printf("%d ", strlen(pstr + 1));     // 6      从字符串中的第二个元素b所在地址开始向后访问    //printf("%d ", strlen(pstr[1]));      // ERROR  同上 读取0x00000062时(十进制:98)发生访问冲突    printf("%d ", strlen(&pstr));        // 随机值      从数组的地址(和数组首元素地址相同)的位置开始向后访问    printf("%d ", strlen(*&pstr));       // 7      同strlen(str),即&str是得到整个数组的地址,对其解引用得到的是整个数组,故为7    printf("%d ", strlen(&pstr + 1));    // 随机值 从数组最后一个元素后面所在内存地址开始访问    printf("%d ", strlen(&pstr[0]));     // 7      从字符串中首元素a地址处开始向后访问    printf("%d ", strlen(&pstr[0] + 1)); // 6      从字符串中第二个元素b地址处开始向后访问    return 0;}

第九:二维数组在sizeof中的应用

int main(){    // 二维数组 用sizeof计算所占字节大小    // 把一个二维数组看成一个一维数组时,则把其每一行看成一个元素,    // 即每个元素又是一个一维数组,其对应的数组名为arr[i], i = 0 1 ... nrow - 1    // i行j列的值:arr[i][j] = *(arr[i] + j) = *(*(arr + i) + j) = *(arr + i)[j]    int arr[2][3] = { 1,2,3,4,5,6 };    int i, j;    for (i = 0; i < 2; i++)    {        for (j = 0; j < 3; j++)        {            printf("%p\t", &arr[i][j]);        }        printf("\n");    }    printf("%d ",  sizeof(arr));      // 24 整个数组所占字节大小:2 * 3 * 4 = 24    printf("%d ", sizeof(arr[0][0])); // 4  数组中第一行第一列值所占字节大小:int|1,为4    printf("%d ", sizeof(arr[0]));    // 12 arr[0]是二维数组中第一个元素|首元素|一维数组的数组名,计算的该数组的整个大小    printf("%d_%d ", sizeof(arr[0] + 1), *(arr[0] +1)); // 4_2, 此时arr[0]是一个一维数组中首元素的地址,+1则代表该一维数组中第二个元素的地址和值    printf("%d ", sizeof(*(arr[0] + 1)));  // 4 | 8 第一行第二列元素所占字节    printf("%d_%p ", sizeof(arr + 1), *(arr + 1));        // 4 | 8 第二行的地址,不是二维数组中第二个元素的地址(arr[1])    printf("%d ", sizeof(*(arr + 1)));    // 12    等价于arr[1] 第二行(一维数组)的地址解引用得到第二行(一维数组),二维数组中第二个元素|一维数组的数组名    printf("%d_%p ", sizeof(&arr[0] + 1), &arr[0] + 1);   // 4 | 8 第二行的地址,一个一维数组的地址    printf("%d ", sizeof(*(&arr[0] + 1)));  // 12 第二行的大小    printf("%d ", sizeof(*arr));            // 12 第一行的大小    printf("%d ", sizeof(arr[3]));          // 12 第四行所对应的一维数组的数组名,代表整个一维数组的大小    return 0;}

第十:公司面试题解析

int main(){    // 解析:    // 1. **++cpp    //    cpp指向的是数组cp中首元素的地址,++cpp则cpp指向数组cp中第二个元素的地址    //    *++cpp: 对其进行解引用,得到cp中第二个元素的内容:c+2    //    **++cpp: 对其进行解引用,得到c+2所指向的内容,而c+2是数组c中第三个元素的地址,即得到数组c中第三个元素    //    数组c中第三个元素为字符串"python"首字母的地址,对其进行打印,则得到python    // 2. *--*++cpp + 3    //    ++cpp,则是cpp指向数组cp中下一个元素的地址,即c+1的地址    //    *++cpp:对其进行解引用,得到其指向的内容:c+1,对其进行--操作,即内容-1,即c+1-1 = c    //    *--*++cpp:对c进行解引用,得到c指向的内容,c为数组c首元素的地址,即得到数组c的首元素,即字符串"hello"首字符的地址    //    对其进行+3操作,即得到字符串"hello"中第二个l字符的地址,对其进行打印,得到lo    //3. *cpp[-2]+3 = *(*(cpp-2)) + 3    //    得到cpp所指向内容的前面第二个内容(c+3)的地址,对其进行解引用得到内容;c+3    //    对其进行及引用,得到c+3所指向的内容,即数组c中第四个元素,即字符串"coming"首字符的地址,对其+3操作,得到字符i的地址,对其打印,得到ing    //4. cpp[-1][-1] + 3 = *(*(cpp-1) - 1) + 3    //    cpp - 1:指向cpp所指向的前面的地址:c+2的地址,解引用得到c+2,即*(c+2 - 1) + 3 = *(c+1) + 3    //    c+1: 是数组c中第二个元素的地址,对其解引用得到数组c中第二个元素,即字符串"world"的首字符的地址, + 1 得到字符o的地址,打印时,得到orld    char* c[] = { "hello", "world", "python", "coming" };    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;}

它们之间的分布情况如下:

结果如下:

©著作权归作者所有:来自51CTO博客作者终极***的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 2021-04-03:给定两个字符串str1和str2,想把str2整体插入到str1中的
  2. 4-2(vector)
  3. 实例ES6演示数组,对象,传参解构; 实例演示访问器属性的get,set操作
  4. maven 仓库地址配置大全
  5. js的解构
  6. 如何在 Apache Hive 中解析 Json 数组
  7. 20201214 Json与pickle数据序列化
  8. 无线不能连接故障又一例
  9. 华为核心交换机配置mac地址白名单接入

随机推荐

  1. Android百度地图之显示地图
  2. Android开发视频教程大总结―23部视频教
  3. Android 渗透测试学习手册 第二章 准备实
  4. Android百度地图导航的那些坑
  5. [转] How to clear cookies and cache of
  6. 和兄弟们聊内存的事
  7. android 笔记2
  8. Android自带的人脸识别
  9. EditText android:imeOptions与inputType
  10. android 终于搞定了判断ScrollView是否滚