当前位置:网站首页>指针和数组(7)
指针和数组(7)
2022-07-28 13:24:00 【51CTO】
(一)关于指针 |
什么是指针
C语言指针是一种派生类型,指针变量的值是计算机内存的地址;
C语法规定使用&获取变量的内存地址,用*获取指针变量所指向内存内部的值。
C语言中,任何类型包括函数类型(函数指针)、指针类型本身(指针的指针,多重指针),都可以派生指针类型。
计算机内存可以看做是由许多字节单元组成的,按照字节编址,每个字节都有固定的地址。例如:
32位机器内存地址空间是2的32次方,也就是4GB大小,地址范围0x0000000-0xffffff。简单理解是每个字节单元是房间,每个地址是房间号,房间号从0开始编号,房间里面存放变量的真正的值。
变量分配地址一般从低地址编号到高地址编号,内存地址一般使用十六进制表示,便于与二进制转换。
声明指针变量
指针变量和整型变量、浮点变量一样,需要声明和初始化使用。
不同数据类型的指针变量的值都是地址常量,只不过其指针地址所指向的变量数据类型是不同的。
声明语法:类型名称 *指针变量标识符;
例如:
char *cp;// 声明指向char型的指针变量cp
int *ip; // 声明指向int型的指针变量ip
float *fp;// 声明指向float型的指针变量fp
double *dp; // 声明指向double型的指针变量dp
指针初始化和赋值
和普通变量一样,指针变量同样可以初始化和赋值。例如
1. char c='a';
char *cp = &c; //获取变量c的地址,赋值初始化字符指针cp
2. int i= 1000;
int *ip = &i; //获取变量c的地址,赋值初始化整型指针ip
3. float f = 1.01f;
float *fp = &f; //获取变量c的地址,赋值初始单精度浮点型指针fp
4. double d = 1.01;
double *dp = &d;//获取变量c的地址,赋值初始化双精度浮点型指针dp
指针变量使用
指针变量使用有两种:
1)输出指针变量的值(即地址);
2)一种是访问指针变量所指向变量的值(即数值)。
注:指针变量的值本质上是无符号整数,因此可以进行加减运算。
例如
运行结果
0062FE98
1000
1000
地址常量和空指针
1.C语言规定,NULL是空指针常量,可以赋值初始化任何类型的指针变量。
2.指针变量的值本质上是无符号整型,因此可以通过强制转换将整型常量赋值给指针变量。
输出结果:
00000000
0000FFEE
3.NULL空指针是来检测指针是否正常,空指针不指向任何位置,访问值为空指针的指针变量所指向的数据时会报错。
4.检查指针是否为空,可以用语句,因为指针变量值本质上可以看做是无符号整数。
以下为常用的4种判空形式:
判空形式1
int *p = NULL;
if(p == NULL){ // 当指针p为空时
...... // do_some_things
}
判空形式2
if(!p) {
...... // do_some_things
}
判空形式3
if(p != NULL) { // 当指针p不为空时
......// do_some_things
}
判空形式4
if(p) {
......// do_some_things
}
指针的运算
指针(地址)支持加减、自增、自减,支持关系运算(大于小于等于),因为指针的值本质上就是无符号整数。
*p++、*p--:表示p指向的变量值本身加减运算,而不是指针地址运算,因为*p的运算符优先级更高。
例如
(二)关于数组 |
什么是数组及其特点
数组是C语言一种派生的数据类型。
数组是一组相同类型的数。其在计算机内部,会分配连续的内存空间保存这组数,该内存空间的大小根据每种数据类型的大小乘以这组数的个数确定。
通常,每个变量声明需要使用标识符来单独声明;那么,当有多个相同类型的变量需要保存时,可以通过定义数组(如:int a[100])来保存数据。
数组特点:
1.数组的长度是确定,需要定义数组保存的数的个数
2.数组中每个数称为元素,元素从0开始编号,当数组长度为n,数组编号范围从0到n-1
3.数组的每个元素访问,简单通过下标运算符,a[0] a[1] ... a[n-1]
4.计算机内部分配给数组一块连续的内存空间,内存地址是连续的,从低地址到高地址
注:C89标准不支持变长数组,C99标准支持变长数组
数组声明
同普通类型一样,数组需要声明定义、初始化。
声明语法:类型 数组名称[数组长度];
其中,类型:整型、浮点型、指针、结构、联合、枚举等对象类型,不包括void和函数类型;
数组名称:任意一个合法的标识符即可;
数组长度:无符号整数,常量表达式,不允许使用变量。
例如
char c[100];// 字符数组
int a[100];// 整数数组,数组长度100
float f[100];// 浮点数数组
double d[100]; // 双精度浮点数数组
struct s sa[100];// 声明结构数组变量sa
union u ua[100];// 声明联合数组变量ua
enum e ea[100]; // 声明枚举数组变量ea
int *pa[100];// 声明int型指针数组pa
struct s *pa[100];// 声明结构指针数组pa
void *pa[100];// 声明void指针数组pa,合法
void (*pa[100])(void); // 声明指向返回值和参数值都为void 函数指针的数组pa
注:数组[]下标运算符优先级高于指针*运算符。
以下不合法情况注意:
void pa[100];// 不合法,void型数组不支持
fun pa[100]; // 不合法,fun是函数名称,函数类型数组不支持
int a[2+5];// 合法,1+5是常量表达式,编译器计算得出6
int a[i+5]; // 不合法,i是变量,数组长度必须是常量表达式
注:i是变量,变量的值在编译时无法得到其真正的值,需要在运行时才能知道。
数组初始化
数组初始化,指给数组中每个元素内存空间存放初始值。
数组长度较大时,一般需要使用循环结构去初始化.
数组元素较少的情况下:数组长度很少时,一般少于10个时,直接赋值初始化。例如
int a[5] = {1,2,3,4,5}; // 通过{}和逗号一一给元素赋值
int a[] = {1,2,3,4,5}; // 等价于上面,编译器会根据初始值个数确定长度,隐式长度
int a[5] = {1,2,3}; // 初始化数个数小于长度,合法,赋值前3个元素的值,其余元素默认初始化为0
int a[5] = {1,2,3,4,5,6};/ 以下不合法,初始化数个数大于长度,编译器会警告
数组元素较多的情况下:数组长度较大,使用循环和下标访问进行初始化。例如
int a[100];
int i;
for(i=0;i<100;i++){
scanf('%d",&a[i]);
}
数组访问
数组元素通过数组下标[]运算符进行访问和修改。
数组元素下标是从0开始计数的,当数组长度为n时,下标最大只能访问n-1。
示例:
数组内存大小及元素个数的计算
sizeof(数组名)可以计算出数组在内存中占据多少字节。
sizeof(数组名)/sizeof(数组名[0])可以计算出数组中有多少个元素个数。
例如:计算数组a的内存大小及元素个数
字符数组和字符串类型
字符串数组形式上一样,区别是字符数组最后一个元素是否是空字符 '\0'。
- 以下是字符数组,保存 hello 五个字符,处理时只能单独访问各个字符,不能作为字符串hello处理。
char a[5]={'h','e','l','l','o'};//字符数组
- 以下同样是字符数组,保存hello和\0 六个字符,即可以作为字符数组处理,也可以作为字符串处理。
char a[6]={'h','e','l','l','o','\0'};//字符串
- 以下声明和定义字符串的方式,C语言没有单独的字符串类型,字符串会转换等同于上述字符串 c[6],因此数组c的长度是6,最后一个字符会是 '\0'。
char a[]=“hello”;//字符串类型声明和初始化
注:字符数组不等于字符串类型,字符串类型一定是最后一个元素是'\0'的字符数组。
多维数组
C语言数组支持多维数组,数组类型进行嵌套,有几维就使用几个方括号[],C语言支持更高维数的数组,一般我们最多使用到三维数组。如
一维数组:int a[100];
二维数组:int a[100][100];
三维数组:int a[100][100][100];
多维数组可以看成是由多个一维数组组成,初始化和访问和普通数组一样,数组下标都是从0开始。
例如,二维数组可以相当于表格,存放n行m列数据,可以按行访问或是按列访问。。
示例:计算二维数组所有元素的和,从行到列开始访问累加。
字符串数组
字符串数组其实是char字符型的二维数组。
字符串是一维char数组;字符串数组是二维数组,保存多个字符串时使用。
例如:char c[2][6];//声明2个一维char数组,每个char数组最多存储6个字符。如果保存字符串,最多保存5个字符,第6个字符必须是'\0'。
示例:如何保存和输出"hello" "world"两个字符串到字符串数组。
输出结果:
hello
world
注:字符串数组长度必须取字符串中最大的长度后加1,因为需要多保存'\0'字符。
数组与指针
数组名称相当于指针常量,因此数组名称可以赋值给对应类型的指针变量,同样指针的特性和运算,可以通过数组名称使用。例如
int a[5] = {1,2,3,4,5};// 声明数组a
int *p = a; // 声明指针p,初始化为数组名称;a相当于int型指针常量
// 以下三种方式等价
printf("%d\n", a[0]); // 访问a[0]
printf("%d\n", a[1]); // 访问a[1]
printf("%d\n", *p); // 访问a[0]
printf("%d\n", *(p+1)); // 访问a[1]
// 使用数组名称a也可以
printf("%d\n", *a); // 访问a[0]
printf("%d\n", *(a+1)); // 访问a[1]
数组和指针区别:
1.sizeof(p)的值是4,因为p是指针类型,sizeof(a)值为20=5*4,a是数组类型。
2.数组类型和指针类型仍是两种不同类型,只是有些特性相似。
3.函数参数允许使用数组[],但是会退化成指针类型,因此本质上函数参数只支持指针类型,不支持数组类型。返回值同样不支持数组.例如
int *f(int a[],int b);等价于:int *f(int *a, int b);。
---------------------------END---------------------------
边栏推荐
- [basic course of flight control development 7] crazy shell · open source formation UAV SPI (barometer data acquisition)
- URL related knowledge points
- 【LVGL事件(Events)】事件在不同组件上的应用(一)
- 【LVGL事件(Events)】事件代码
- 【LeetCode】1331. 数组序号转换
- Understanding of "image denoising using an improved generic advantageous network with Wasserstein distance"
- What is a spin lock? A spin lock means that when a thread attempts to acquire a lock, if the lock has been occupied by other threads, it will always cycle to detect whether the lock has been released,
- 数据库系统概论(第5版)补充习题——第一章 绪论
- How to effectively conduct the review meeting (Part 1)?
- Collaborative office tools: Online whiteboard is in its infancy, and online design has become a red sea
猜你喜欢

解决uniapp微信小程序canvas不能引入字体的问题

JMeter installation tutorial and login add token

MySQL开发技巧——视图

Qt5开发从入门到精通——第一篇概述

MVC模型:日历系统

bgp实验

成为绿色数据中心新样板,东莞华为云数据中心是怎样炼成的?

Qt5 development from introduction to mastery -- the first overview

Discrete logarithm problem (DLP) & Diffie Hellman problem (DHP)

《机器学习》(周志华) 第6章 支持向量 学习心得 笔记
随机推荐
深度学习基础----GNN谱域和空域 (不断完善更新积累)
Understand the principle behind the virtual list, and easily realize the virtual list
webSocket聊天
走进音视频的世界——FLV视频封装格式
利用反射构建一棵菜单生成树
How to effectively conduct the review meeting (Part 1)?
Several solutions to spanning
83. (cesium home) how the cesium example works
Four ways to create thread pools
83.(cesium之家)cesium示例如何运行
天气这么热太阳能发电不得起飞喽啊?喽啊个头……
解决uniapp微信小程序canvas不能引入字体的问题
离散对数问题(DLP) && Diffie-Hellman问题(DHP)
What is gossip (E-Net gossip)
[try to hack] hfish honeypot deployment
每日一题——奖学金
【翻译】盐业公司来Linkerd公司是为了负载平衡,留下来是为了效率、可靠性和性能。...
IP黑白名单
Implementation of StrCmp, strstr, memcpy, memmove
IP black and white list