8.1 数组名和指针  

int a;
int b[10];

 a称为一个标量,表示一个单一的值,变量的类型是整数。

 b是数组,b[1]的类型是整数,b是一个指针常量,表示数组第一个元素的地址。b的类型取决于数组的类型,在这里b是指向int的常量指针,如果是其他类型的数组,那么就是指向其他类型的指针常量

 但是数组和指针并不相同,数组是有确定数量的元素,而指针只是一个标量,编译器有数组名来记住这些属性,当数组名在表达式中使用时,编译器才会为他产生一个指针常量。数组名是指针常量,所以是不可以修改的,他指向内存中数组的起始位置,第一个元素的位置。

  只有在两种场合下,数组名并不用指针常量来表示:

  数组名当做sizeof操作数时返回数组的长度

  &操作符,取一个数组名的地址,所产生的是一个指向数组的指针,而不是指向指针的指针

  如下:

#include <stdio.h>

int main()
{
int a[10] = {}; printf("%lu\n", sizeof a);
return 0;
}

  输出40,sizeof的返回值是long unsigned int。

#include <stdio.h>

int main()
{
int a[3] = {1, 2, 3};
int b[3] = {4, 5, 6};
int *c; //&a[0]指向第一个元素的指针,合法
c = &a[0]; //b为常量所以不合法,指针的复制应该通过循环来进行复制
b = a;
printf("%lu\n", sizeof a);
return 0;
}

  8.1.2 下标

在之前的上下文环境中,

*(b + 3)

首先,b指向数组的第一个元素的指针常量,这里加上3个整数长度,如果是float类型的数组,会加上三个float类型的长度,这里所加的长度是取决于数组的类型,然后间接访问这个新位置。除了优先级之外和下标访问完全相同。等价与

b[3]

所以对于下面的表达式也是合法的:

3[b];

转换成指针间接访问表达式:

*(3 + b);

由于编译器实现下标的方法,所以这两种形式并无差别。

8.19 初始化

#include <stdio.h>

int main()
{
//非法,不可以把4个数放到三个位置里面
int a[3] = {1, 2, 3, 4};
//合法,缺省的值为0,实际上b是 [0, 0, 0]数组
int b[3] = {}; return 0;
}

  如果声明中为给出数组的长度,编译器就把数组的长度设置为,刚刚好能够容纳初始元素的值的长度。

//a的长度为4
int a[] = {1, 2, 3, 4};

  字符数组初始化,

#include <stdio.h>

int main()
{
//下面这两种方式都是字符数组初始化,注意第二个不是字符串常量的初始化
char message1[] = {'m', 'e' , 's', 's', 'a', 'g', 'e', '\0'};
char message2[] = "message";
//下面是字符串常量的初始化
char *message3 = "message"; printf("%s\n", message2);
return 0;
}

  当初始化一个数组时,字符串常量初始化的是一个字符串列表,其他地方是字符串常量。

  多维数组:

  多维数组是指数组内的元素也是数组的数组,例如

int matrix[10][6];

  对于matrix,它有十个元素,其中的每个元素是一个长度为6的数组。同时,matrix是指向数组第一个元素的指针,这里matrix是指向有6个整数的数组的指针,matrix的类型为

int (*p)[6] = matrix;

此时,对面matrix的增量运算

*(matrix + 1);

  数组名的运算所加的长度取决于数组的元素的类型,这里数组内元素是有6个整数的数组。所以matrix  + 1,移动了6 个整数长度的位置。matrix + 1指向数组第二行,

#include <stdio.h>

int main()
{ int matrix[10][6] = {};
//[]优先级较高,所以要加()
int (*matrix2)[6] = matrix + 1;
//*matrix2和*matrix分别指向数组第一行数组的第一个值,和第二行数组的第一个值
printf("%lu\n", *matrix2 - *matrix); return 0;
}

  输出6,位置相差6个int的长度。

  当需要在多维数组上进行指针运算时,需要指定每个数组元素的长度。

#include <stdio.h>

int main()
{ int matrix[10][6] = {};
//此时进行运算,讲根据空数组的长度进行调整,与零相乘
int (*p)[] = matrix;
//正确的声明应该加上多维数组的长度,这样编译器就可以进行下标运算
int (*p)[6] = matrix; return 0;
}

  同样,多维数组的声明时,需要自动计算长度也要指定多维的长度。

//只有matrix[0][0]被声明为1,其他均为0
int matrix[][6] = {
{1},
};

  指针数组:

#include <stdio.h>

int main()
{
//指针数组,keyword1数组内都是指针。
char const *keyword1[] = {"name", "age"};
//字符矩阵,keyword2数组内都是长度为10的字符数组。
char const keyword2[][10] = {"name", "age"}; printf("%lu\n", sizeof keyword1[1]);
printf("%lu\n", sizeof keyword2[1]); return 0;
}

  输出:8 和 10。8是指针的大小,10是keyword2中每个矩阵的大小。

C和指针 第八章 数组的更多相关文章

  1. PHP中使用数组指针函数操作数组示例

    数组的内部指针是数组内部的组织机制,指向一个数组中的某个元素.默认是指向数组中第一个元素通过移动或改变指针的位置,可以访问数组中的任意元素.对于数组指针的控制PHP提供了以下几个内建函数可以利用. ★ ...

  2. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  3. C++笔记-数组指针/二维数组转换指针

    参考资料: 1. 作者 BensonLaur  :https://www.cnblogs.com/BensonLaur/p/6367077.html 2. https://blog.csdn.net/ ...

  4. C语言 指针基础篇 数组,函数与指针的运用 2 14

    下面看看如何在函数中运用指针吧 下面是往函数传入指针的简单操作,不是传入数组的.判断一个a是否大于b是的话给,是的话对其进行操作,不是的话就直接返回. #include <stdio.h> ...

  5. C和C指针小记(十三)-数组

    1.1 一维数组 一维数组的声明: int a[10]; 这里a就是一个数组. 数组a的类型就是一个指向整型的常量指针. 但是数组和指针是**不相同**的. **数组具有特定数量的元素,而指针只是一个 ...

  6. [C++]指针和指向数组的指针[一维数组与指针]

     1.一维数组与指针      形如:int型 数组 a[10]                1)&a[0]  地址常量;地址类型:int *型   ; 存储数组a的首地址          ...

  7. #运算符、不同的指针类型、数组和指针、指针运算、堆、栈、静态区、只读区、下标VS指针

    #运算符:用于在预编译期将宏参数转换为字符串 #define CONVERS(x)  #x   //注:没用双引号包括. 不同类型的指针占用的内存空间大小相同. 局部变量 定义: a[5]; 打印a[ ...

  8. C语言数组指针(指向数组的指针)

    注意:数组指针的定义,与指针数组的区别 转载:http://c.biancheng.net/cpp/biancheng/view/162.html 指向多维数组元素的指针变量 ① 指向数组元素的指针变 ...

  9. C语言指针系列 - 一级指针.一维数组,二级指针,二维数组,指针数组,数组指针,函数指针,指针函数

    1. 数组名 C语言中的数组名是一个特殊的存在, 从本质上来讲, 数组名是一个地址, 我们可以打印一个指针的值,和打印一个数组的值来观察出这个本质: int nArray[10] ={ 0 }; in ...

随机推荐

  1. C语言:socket简单模拟http请求

    #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netine ...

  2. flex引起height:100%失效

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  3. echarts在.Net中使用实例(一) 简单的Demo

    前言 这个必须要有前言,即便很短,对于有强迫症的人来说不容易啊.言归正传,之前做图一直使用rdlc自带的格式,虽然任务完成,但是一直觉得不太美观, 空余时间开始找其他的插件,终于找到了Highchar ...

  4. iOS 底层框架的浅析

    1.简介 IOS是由苹果公司为iPhone.iPod touch和iPad等设备开发的操作系统. 2.知识点 iPhone OS(现在叫iOS)是iPhone, iPod touch 和 iPad 设 ...

  5. 20145233 2016-2017 1 linux题目总结

    20145233 2016-2017 1 linux题目总结 第一周考试知识汇总 判断:实验楼环境中所有的默认系统用户名和密码均为 shiyanlou.(x ). 填空:Linux Bash中,Ctr ...

  6. 我为什么还要造轮子?欠踹?Monk.UI表单美化插件诞生记!

    背景 目前市场上有很多表单美化的UI,做的都挺不错,但是他们都有一个共同点,那就是90%以上都是前端工程师开发的,导致我们引入这些UI的时候,很难和程序绑定.所以作为程序员的我,下了一个决定!我要自己 ...

  7. react.js 生命周期componentDidUpdate的另类用法:防止页面过渡刷新

    场景:数据新增成功之后,需要返回原来的查询表,这时候的查询,需要使用react的生命周期:componentDidUpdate componentDidUpdate() 这个生命周期的作用是当prop ...

  8. 使用powershell链接到Azure

    一:针对传统的的Azure 的登陆界面: (ASM) 1. 正常来说是 现在本地创建证书文件,然后上传文件,以便本地计算机和Azure建立可靠的安全连接 Get-AzurePublishSetting ...

  9. c# Linq查询

    c#提供的ling查询极大的遍历了集合的查询过程,且使用简单方便,非常的有用. 下面将分别用简单的例子说明:ling基本查询.延迟查询属性.类型筛选.复合from字句.多级排序.分组查询.联合查询.合 ...

  10. Alpha阶段项目Postmortem

    以下对成员名字的简称: 陈鸿超 = 陈1 陈彦吉 = 陈2 石浩然 = 石 韩青长 = 韩 1. 设想和目标 1.1 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? ...