深入理解C语言-深入理解数组
数组,作为C语言中常见的复杂数据类型,了解其本质有助于深入了解C语言
数组概念
元素类型角度:数组是相同类型的变量的有序集合测试指针变量占有内存空间大小
内存角度:联系的一大片内存空间

数组初始化
数组元素的个数可以显示或隐式指定
数组的初始化可以用{ 0 },也可以使用memset初始化
int main()
{
int i = 0;
int a[10] = { 1, 2 }; //其他初始化为0
int b[] = { 1, 2 };
int c[20] = { 0 };
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
memset(a, 0, sizeof(a));
getchar();
return 0;
}
关于数组名的一些问题
- 数组首元素的地址和数组地址是两个不同的概念,前者代表一个元素大小,后者代表一个和数组大小
- 数组名代表数组首元素的地址,它是个常量,其本质就是一个变量的别名
- 数组首元素的地址和数组的地址值相等
- 数组的类型由元素类型和数组大小共同决定,e.g. int[5]
数组类型的自定义
typedef int(MYINT5)[5];
···
MYINT5i Array; //int Array[5];
数组指针
数组指针用于指向一个数组
- 通过数组类型定义数组指针
typedef int(ArrayType)[5];
ArrayType* pointer;
用数组类型加*定义一个数组指针
void main(void)
{
int a[5];//声明一个数组类型
typedef int(MYINT5)[5];//用数组类型 加*,定义一个数组指针变量
MYINT5 *array;
array = &a;
for (i = 0; i < 5; i++)
{
(*array)[i] = i;
}
for (i = 0; i < 5; i++)
{
printf("\n%d %d", a[i], (*array)[i]);
}
}
- 声明一个数组指针类型
typedef int (*MyPointer)[5];
定义一个数组指针类型,然后用类型定义变量
void main(void)
{
int b[5];//声明一个数组指针类型
typedef int (*MyPointer)[5];//用数组指针类型,去定义一个变量
MyPointer mypoint;
mypoint= &b;
for (i = 0; i < 5; i++)
{
(*mypoint)[i] = i;
}
for (i = 0; i < 5; i++)
{
printf("\n%d %d", b[i], (*mypoint)[i]);
}
}
- 直接定义
int (*pointer)[n];
直接定义一个数组指针变量
void main(void)
{
int c[5];
int (*pointer)[5] = &c;//直接声明一个数组指针变量
for (i = 0; i < 5; i++)
{
(*pointer)[i] = i;
}
for (i = 0; i < 5; i++)
{
printf("\n%d %d", c[i], (*pointer)[i]);
}
}
一维数组本质
int a[5] 一维数组名代表数组首元素的地址
int a[5] ==> a的类型为int*
二维数组本质
实验:
int arr[3][4];
printf("arr:%d, arr + 1:%d", arr, arr + 1);
此时输出打印的结果相差16,也就是4 * 4,通过这个契机,得出二维数组名的本质
arr的本质是一个数组指针,每次向后移动一维的长度
| 说明 | 写法 | 写法 | 写法 |
|---|---|---|---|
| 第0行第1列元素地址 | a [0]+1 |
*a+1 |
&a[0][1] |
| 第1行第2列元素地址 | a [1]+2 |
*(a+1)+2 |
&a[1][2] |
| 第 i 行第 j 列元素地址 | a [i]+j |
*(a+i)+j |
&a[i][j] |
| 第1行第2列元素的值 | *(a [1]+2) |
*( *(a+1)+2) |
a[1][2] |
| 第 i 行第 j 列元素的值 | *(a [i]+j) |
*( *(a+i)+j) |
a[i][j] |
正是因为有了这些特性,二维数组在做函数参数的时候,会退化为二级指针,这样设计的目的在于参数传递的时候不用传递太多数据,数组指针做函数参数,一般只会使用到二维
char buf[3][4] ==> char buf[][4] ==> char (*buf)[4]
多维数组的线性存储特性
多维数组在内存中是线性存储的,即按照低维到高维线性排序
char buf[2][3];
buf[0][0]·buf[0][1]·buf[0][2]·buf[1][0]·buf[1][1]·buf[1][2]
数组做函数参数
由于C语言中只会以机械式的值拷贝的方式传递参数(实参把值传给形参),所以在数组做函数参数的时候,是没法知道数组大小的,需要额外传递数组大小数据
int fun(char a[20], size_t b)
{
printf("%d\t%d",b,sizeof(a));
}
二维数组可以看做是一维数组
二维数组中的每个元素是一维数组
二维数组参数中第一维的参数可以省略
void f(int a[5]); ==> void f(int a[]); ==> void f(int* a);
void g(int a[3][3]) ==> void g(int a[][3]); ==> void g(int (*a)[3]);
深入理解C语言-深入理解数组的更多相关文章
- 深入理解C语言-深入理解指针
关于指针,其是C语言的重点,C语言学的好坏,其实就是指针学的好坏.其实指针并不复杂,学习指针,要正确的理解指针. 指针是一种数据类型 指针也是一种变量,占有内存空间,用来保存内存地址 指针就是告诉编译 ...
- 深入理解C语言-深入理解void
void的字面意思是"无类型",void *则为"无类型指针",void *可以指向任何类型的数据 void含义 void几乎只有注释和限制程序的作用,定义一个 ...
- 深入理解C语言-深入理解内存四区
数组与指针 当数组做函数参数的时候,会退化为一个指针 此时在函数内是得不到数组大小的 因此,数组做函数参数的时候需要传递数组大小,也就是多传递一个参数 void func(int arr[], int ...
- 深入理解C语言中的指针与数组之指针篇
转载于http://blog.csdn.net/hinyunsin/article/details/6662851 前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本 ...
- 深入理解C语言中的指针与数组之指针篇(转载)
前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本所在.相信,任意一家公司如果想要考察一个人对C语言的理解,指针和数组绝对是必考的一部分. 但是之前一方面之前一直在忙各种事情 ...
- 深入理解c语言_从编译器的角度考虑问题_纪念Dennis Ritchie先生
开源中国: Dennis Ritchie教授过世了,他发明了C语言,一个影响深远并彻底改变世界的计算机语言.一门经历40多年的到今天还长盛不训的语言,今天很多语言都受到C的影 响,C++,Java,C ...
- "深入理解C语言" 指针
本文对coolshell中的"深入理解C语言"这篇文章中提到的指针问题, 进行简要的分析. #include <stdio.h> int main(void){ ]; ...
- 理解C语言中指针的声明以及复杂声明的语法
昨天刚把<C程序设计语言>中"指针与数组"章节读完,最终把心中的疑惑彻底解开了.如今记录下我对指针声明的理解.顺便说下怎样在C语言中创建复杂声明以及读懂复杂声明. 本文 ...
- 【转载】理解C语言中的关键字extern
原文:理解C语言中的关键字extern 最近写了一段C程序,编译时出现变量重复定义的错误,自己查看没发现错误.使用Google发现,自己对extern理解不透彻,我搜到了这篇文章,写得不错.我拙劣的翻 ...
随机推荐
- 【Python之路】特别篇--Django瀑布流实现
瀑布流 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早采用此布局的网站是Pinteres ...
- contents() 查找匹配元素内部所有的子节点(包括文本节点)。如果元素是一个iframe,则查找文档内容
contents() V1.2概述 查找匹配元素内部所有的子节点(包括文本节点).如果元素是一个iframe,则查找文档内容 示例 描述:大理石平台检定规程 查找所有文本节点并加粗 HTML 代码 ...
- react须知
1. JSX是什么? 1)JSX是一种facebook发明的语法.就是将HTML和JS 可以同时书写.其实是一种js的语法糖. 但是浏览器不能识别,需要通过babel-loader来转译. @babe ...
- CUDA-F-5-5-常量内存
title: [CUDA 基础]5.5 常量内存 categories: - CUDA - Freshman tags: - CUDA常量内存 - CUDA只读缓存 toc: true date: 2 ...
- Java中properties可以读取,但是里面的数据读取不到
今天配置一个项目jdbc.properties这个文件里面的键值总是读取不到,刚开始以为是文件没有读取到,但是测试是读取到的,再排查键值是不是写错了, 后来发现键值是对的,这就很奇怪了 比较是没有任何 ...
- Mac Appium环境搭建
安装brew ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)" 安装java brew install ...
- 利用django框架,手把手教你搭建数据可视化系统(一)
如何使用django去构建数据可视化的 web,可视化的结果可以呈现在web上. 使用django的MTV模型搭建网站 基础铺垫-MTV模型 Created with Raphaël 2.1.0Req ...
- javascript中的Date数据类型
javascript中,Date代表日期对象,其常见的用法如下: 一.Date的构造函数 有四种形式的Date构造函数,详见下面代码的注释: //1.构造函数没有参数,则返回当前日期的Date对象 v ...
- IDEA项目结构只剩下了pom,而代码都找不到了
大体效果就是下面这个样子的, 只剩下一个pom文件了. 解决方式: 本来想彻底排查下的,但是最后发现 直接删除.idea文件, 重新引入项目,就可以解决,可能就是编译器发神经吧 下面是排查的过程,不过 ...
- solr安装记录
[root@localhost bin]# ./solr start -force*** [WARN] *** Your open file limit is currently 1024. It ...