复合型数据结构:C数组
1 数组的特例:字符串
在C语言中,定义一个字符串样式的数组,有如下两种方式:
char arr[] = "abcdefg";
char *str = "abcdefg";
这两种方式有什么区别呢?别看它们表面上都差不多,其实差远了!
1.1 字符数组定义字符串——从一而终
这里的数组名 arr:实际上是个变种的“指针常量”,
(1)常量说明了“绑定关系”不能变,这种定义字符串的方式,会在栈帧里面存放“abcdefg\0”这一个字符数组实体,arr 在函数体的整个生命周期里面不能再绑定其他的东西!直到这个函数体的消亡,一起被销毁;
(2)“变种”有3个含义:
① 共享房子的大小:arr的大小,将等于"abcdefg\0"的大小
② 共享房子的位置:arr的地址,将等于战阵中"abcdefg\0"的首地址
③ 相敬如宾:arr这个指针不能随便去"abcdefg\0"里面随便乱指,只能通过arr[0],arr[1]……这种固定的方式去访问“abcdefg\0”中的内容
1.2 字符指针定义字符串——登徒浪子
这里的指针 char *str:是一个指针变量,它就是一个登徒浪子!
(1)变量说明了“绑定关系”可以随时变!str在整个函数体的生命周期中,不一定非要绑定"abcdefg\0"这一个字符串常量,看它不顺眼了,可以改!
(2)“登徒浪子”是相对独立自主的!
① str 拥有自己独立的大小(就是指针的大小,与机器字长有关),而与字符串常量"abcdefg\0"的大小无关;
② str 拥有自己独立的地址,在栈帧之中占据一席地位,独立地分配了栈帧中的字节!
③ str 特别喜欢指指点点,可以使用str++, str–这样的方式,在 “abcdefg\0” 里面指来指去!
1.3 测试代码
#include <stdio.h>
int main(int argc, char *argv[]){char arr[] = "abcdefh";char *str = "abcdefh";printf("argv = 0x%x\r\n", &argv);printf("argc = 0x%x\r\n", &argc);printf("adress of arr = 0x%x\r\n", &arr);printf("adress of char *str = 0x%x\r\n", &str);printf("adress of arr[0] = 0x%x\r\n", &arr[0]);printf("adress of str[0] = 0x%x\r\n", &str[0]);printf("adress of str[1] = 0x%x\r\n", &str[1]);printf("arr[1] = \'%c\'\r\n", *(arr + 1));printf("arr[0] = \'%c\'\r\n", *arr);printf("*str++ = \'%c\'\r\n", *str++);printf("now, \"str\" points to = \'%c\'\r\n", *str);printf("str-- = \'%c\'\r\n", *str--);printf("now, \"str\" points to \'%c\'\r\n", *str);return 0;
}
1.4 栈帧结构
2 数组
类型 | 说明 |
---|---|
静态数组 | 数组的大小不能变 |
动态数组 | 数组的大小可以动态改变 |
2.1 静态数组
2.1.1 数组测试代码
#include <stdio.h>int main(int argc, char *argv[]){int i = 10;int j = 20;int array[4] = {1, 2, 3, 4};int *p = array;printf("argv = 0x%x\r\n", &argv);printf("argc = 0x%x\r\n", &argc);printf("int variable address = 0x%x\r\n", &i);printf("int variable address = 0x%x\r\n", &j);printf("array 0 address = 0x%x\r\n", &array[0]);printf("array 1 address = 0x%x\r\n", &array[1]);printf("array 2 address = 0x%x\r\n", &array[2]);printf("array 3 address = 0x%x\r\n", &array[3]);printf("pointer address = 0x%x\r\n", &p);printf("int size %d", sizeof(int));return 0;
}
2.1.2 栈帧结构
2.2 动态数组
C99 以上是支持“动态数组”的,可以使用如下语句:
int arr[i];
这个 i 是个变量,C99以下,不能这样玩,需要使用 malloc() 手动实现动态数组,使用 realloc() 可以对数组长度动态地进行调整,实现方法如下:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>#define ARR_SIZE 8
int main(int argc, char *argv[]){int *dynamic_arr = (int *)malloc(ARR_SIZE * sizeof(int)); // Creating a dynamic arrayassert(dynamic_arr != NULL);for(int i = 0; i < ARR_SIZE; i ++){ // Printing the dynamic arrayprintf("dynamic_arr[%d] = %d \r\n", i, dynamic_arr[i]);}for(int i = 0; i < ARR_SIZE; i++){ // Initializing the dynamic arraydynamic_arr[i] = 0;}for(int i = 0; i < ARR_SIZE; i ++){ // Printing the dynamic arrayprintf("dynamic_arr[%d] = %d \r\n", i, dynamic_arr[i]);}/******** Adjusting the length of the dynamic array ********/dynamic_arr = (int *)realloc(dynamic_arr, 16 * sizeof(int)); for(int i = 0; i < 16; i ++){ // Printing the new dynamic arrayprintf("dynamic_arr[%d] = %d \r\n", i, dynamic_arr[i]);}free(dynamic_arr); // Destroy the dynamic arrayreturn 0;
}
3 指针数组和数组指针
注意:“各种括号” 的优先级比 “*” 高!
类别 | 示例 | 说明 | 应用 |
---|---|---|---|
指针数组 | char *str[8]\color{red}str[8]str[8] | 下标[8] 先结合,是数组,数组里每个单元放一个指针 | 函数入参,接收“字符串数组” |
数组指针 | int (∗pArr\color{red}*pArr∗pArr)[4] | 括号() 先结合,是指针,指针指向一个int a[4] 样式数组 | 函数入参,接收“二维数组” |
3.1 用数组指针接收“二维数组”
int print_2Array(int (*pArr)[4], int len){for(int i = 0; i < len; i++){for(int j = 0; j < 4; j++){printf("|%-4d", pArr[i][j]);}printf("|\r\n");}
}
3.2 用二级指针接收“指针数组”
int print_strings(char **str, int len){for(int i = 0; i < len; i++){printf("|%-16s|\r\n", str[i]); // 1-level deference }
}
3.3 测试例程
#include <stdio.h>
int main(int argc, char *argv[]){char *str[8] = {"Alice","Danny","Jenny","Red","Xiaoming","Alex","Angel","Jack"};int arr[6][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 0, 1, 2},{3, 4, 5, 6},{7, 8, 9, 0},{1, 2, 3, 4},};int (*pArr)[4] = arr;print_strings(str, sizeof(str) / sizeof(void *));print_2Array(pArr, sizeof(arr) / sizeof(arr[0]));printf("size of [arr] is %d bytes\r\n", sizeof(arr));printf("size of [pArr] is %d bytes\r\n", sizeof(pArr));return 0;
}
复合型数据结构:C数组相关推荐
- 数据结构之数组定义及基本操作(转)
数据结构之数组定义及基本操作数据结构中最基本的一个结构就是线性结构,而线性结构又分为连续存储结构和离散存储结构.所谓的连续存储结构其实就是数组.数组本质其实也是数据的一种存储方式,既然有了数据的存储, ...
- 009 数据结构逆向—数组(困难版)
文章目录 前言 数组逆向 通过人物血量查找人物属性 调call取对象 call内追局部变量 逆向加密数组下标 分析人物属性 总结 前言 通过之前的分析,我们已经对数组结构有了一个简单的了解,这次就用幻 ...
- 008 数据结构逆向—数组(简单版)
文章目录 前言 逆向背包数组 一维背包数组 二维背包数组 数组结构分析 总结 前言 对于游戏逆向来说,核心需求其实就只有两个 追踪游戏数据 定位游戏功能call 对于追踪游戏数据来说,单纯从一个寄存器 ...
- 基于java的数据结构学习——数组实现的栈以及简单应用C++实现
基于java的数据结构学习--数组实现的栈以及简单应用的 C++ 实现 源码: // // Created by PC-Saw on 2019/1/3. //#ifndef DATA_STRUCTUR ...
- 数据结构 判断数组元素是否互不相同
4.18 数据结构 判断数组元素是否互不相同 -----题目 设二维数组a.b 含有m*n 个整数.写一个算法判断a,b两个数组中所有元素是否互不相同?输出相关信息 a[4][3]={1,2,3,4, ...
- Java版数据结构之数组模拟环形队列demo
Java版数据结构之数组模拟环形队列demo 我的代码仓库:https://github.com/zhuangbinan/datastructure 类 CircleArray package clu ...
- 数据结构之数组及动态数组剖析
数据结构之数组及动态数组剖析 文章目录 数据结构之数组及动态数组剖析 概述 动态数组实现的原理 实践编写动态数组类 时间复杂度分析 数组对数器 参考代码 相关链接 公众号 参考 概述 数组是在程序设计 ...
- 数据结构(数组结构、链表结构)
本来第一篇文章准备写点关于map的,但是考虑到map中可能也牵扯到数据结构,所以先随便写点就当做铺垫吧! 数据结构: 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合 1.集合 数据结构中的 ...
- 第七周--数据结构--队列数组
/* *第七周--数据结构--队列数组 *Copyright (c) 2015 烟台大学计算机与控制工程学院 *All right reserved. *文件名称:li ...
- 数据结构(数组)的特点以及优缺点
数据结构(数组)的特点以及优缺点 数组这种数据结构是我们在java开发中非常常见的.所以借用这篇文章来分析数组的特点以及他的优缺点. 特点一 数组的读取和更改数据的效率是所有数据据结构中最高的. 数组 ...
最新文章
- 全链路监控细节和难点剖析!
- char和byte的区别
- java面向对象第六章
- python列出文件夹所有文件_python列出文件夹所有文件有哪些方法?
- 洛谷 P2184 贪婪大陆 解题报告
- 鸽子 迷信_人工智能如何帮助我战胜鸽子
- [转载] 湖北:星空团队——海燕计划
- 管壁式换热器cad图纸_一文详解换热器技术问答,真的都是珍藏版!
- 你知道直方图都能干啥?
- dell2900服务器做系统,dell2900如何重装系统
- Office - Excel如何查询重复值数量
- 分布式定时任务框架Uncode-Schedule技术介绍
- 编码,隐匿在计算机软硬件背后的语言读书笔记(1)
- python批量压缩图片_Python图片批量压缩到指定大小并将JPG转为PNG格式
- Python绘制美国队长盾牌
- Photoshop学习(二):换色
- mysql引擎与优化
- 目标检测中Regional Proposal到底是什么,RPN和Region Proposal、Proposals三者联系
- 云文档服务器开小差,回首初中作文
- 伪装目标检测(Camouflage Object Detection)部分经典论文汇总