10深入理解C指针之---指针运算和比较
该系列文章源于《深入理解C指针》的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教。
指针运算有很多种,主要有指针的声明*、指针的解引*、指针指向(*).或->、指针+、指针-、指针==、指针!=、指针>、指针>=、指针<、指针<=、指针转换(数据类型)。
通过代码:
#include <stdio.h> int main(int argc, char **argv)
{
char charVar;
short shortVar;
int intVar;
long longVar;
float floatVar;
double doubleVar; printf("不同数据类型的长度如下:\n");
printf("数据类型\t\t长度(字节)\n");
printf("char\t\t\t %d\n", sizeof(charVar));
printf("short\t\t\t %d\n", sizeof(shortVar));
printf("int\t\t\t %d\n", sizeof(intVar));
printf("long\t\t\t %d\n", sizeof(longVar));
printf("float\t\t\t %d\n", sizeof(floatVar));
printf("double\t\t\t %d\n", sizeof(doubleVar)); return ;
}
代码结果:
不同数据类型的长度如下:
数据类型 长度(字节)
char
short
int
long
float
double
不同系统的基本数据类型可能稍微不同,请自己测试。知道自己系统的基本数据类型的大小之后,就可以继续学习下面的内容了,指针的声明和解引,前面已经学习过,下面主要进行其他部分。
一、指针指向->:用于访问结构指针引用的字段内容,是(*).的简化版本而已,
1、定义:可以通过指针方便快捷的访问结构的字段,而且书写更加简单方便,可以减少两次敲击键盘的次数
2、特征:
1)、使用前需要声明结构体
2)、使用前需要声明结构体指针
3)、可以使用->指针指向访问结构体指针的字段
4)、也可以使用(*).解引指针和成员运算符访问结构体指针的字段
3、应用:
1)、结构体的声明方式是非常多样化的,不同的声明方式,使用方式略有不同
2)、使用结构体指针需要先分配内存
3)、如果结构体中含有指针,需要二次分配内存
4)、如果结构体中含有指针,释放内存顺序与分配内存顺序完全相反
代码如下:代码很简单,仔细阅读即可:
#include <stdio.h>
#include <string.h>
#include <stdlib.h> int main(int argc, char **argv)
{
//结构体的普通声明
struct _person{
char* firstName;
char* lastName;
char* title;
int age;
};
struct _person* person1;
person1 = (struct _person*)malloc(sizeof(struct _person));
(*person1).firstName = (char*)malloc(sizeof(char) * );
strcpy((*person1).firstName, "zhang");
(*person1).lastName = (char*)malloc(sizeof(char) * );
strcpy((*person1).lastName, "san");
(*person1).title = (char*)malloc(sizeof(char) * );
strcpy((*person1).title, "A");
(*person1).age = ; printf("The struct _person *person1 info:\n");
printf("(*person1).firstName: %s\n", (*person1).firstName);
printf("(*person1).lastName: %s\n", (*person1).lastName);
printf("(*person1).title: %s\n", (*person1).title);
printf("(*person1).age: %d\n", (*person1).age); free((*person1).firstName);
free((*person1).lastName);
free((*person1).title);
free(person1); struct _person* person2;
person2 = (struct _person*)malloc(sizeof(struct _person));
person2->firstName = (char*)malloc(sizeof(char) * );
strcpy(person2->firstName, "li");
person2->lastName = (char*)malloc(sizeof(char) * );
strcpy(person2->lastName, "si");
person2->title = (char*)malloc(sizeof(char) * );
strcpy(person2->title, "B");
person2->age = ; printf("The struct _person *person2 info:\n");
printf("person2->firstName: %s\n", person2->firstName);
printf("person2->lastName: %s\n", person2->lastName);
printf("person2->title: %s\n", person2->title);
printf("person2->age: %d\n", person2->age); free(person2->firstName);
free(person2->lastName);
free(person2->title);
free(person2); //结构体的高级声明,声明方式不一样,使用方式稍微有点不同
typedef struct _personNew{
char* firstName;
char* lastName;
char* title;
int age;
} Person; Person* person3;
person3 = (Person*)malloc(sizeof(Person));
(*person3).firstName = (char*)malloc(sizeof(char) * );
strcpy((*person3).firstName, "wang");
(*person3).lastName = (char*)malloc(sizeof(char) * );
strcpy((*person3).lastName, "wu");
(*person3).title = (char*)malloc(sizeof(char) * );
strcpy((*person3).title, "C");
(*person3).age = ; printf("The struct _person *person3 info:\n");
printf("(*person3).firstName: %s\n", (*person3).firstName);
printf("(*person3).lastName: %s\n", (*person3).lastName);
printf("(*person3).title: %s\n", (*person3).title);
printf("(*person3).age: %d\n", (*person3).age); free((*person3).firstName);
free((*person3).lastName);
free((*person3).title);
free(person3); Person* person4;
person4 = (Person*)malloc(sizeof(Person));
person4->firstName = (char*)malloc(sizeof(char) * );
strcpy(person4->firstName, "zhao");
person4->lastName = (char*)malloc(sizeof(char) * );
strcpy(person4->lastName, "liu");
person4->title = (char*)malloc(sizeof(char) * );
strcpy(person4->title, "D");
person4->age = ; printf("The struct _person *person4 info:\n");
printf("person4->firstName: %s\n", person4->firstName);
printf("person4->lastName: %s\n", person4->lastName);
printf("person4->title: %s\n", person4->title);
printf("person4->age: %d\n", person4->age); free(person4->firstName);
free(person4->lastName);
free(person4->title);
free(person4); typedef struct _personNewN{
char* firstName;
char* lastName;
char* title;
int age;
} *PersonN; PersonN person5;
person5 = (PersonN)malloc(sizeof(PersonN));
(*person5).firstName = (char*)malloc(sizeof(char) * );
strcpy((*person5).firstName, "zhou");
(*person5).lastName = (char*)malloc(sizeof(char) * );
strcpy((*person5).lastName, "qi");
(*person5).title = (char*)malloc(sizeof(char) * );
strcpy((*person5).title, "E");
(*person5).age = ; printf("The struct _person *person5 info:\n");
printf("(*person5).firstName: %s\n", (*person5).firstName);
printf("(*person5).lastName: %s\n", (*person5).lastName);
printf("(*person5).title: %s\n", (*person5).title);
printf("(*person5).age: %d\n", (*person5).age); free((*person5).firstName);
free((*person5).lastName);
free((*person5).title);
free(person5); PersonN person6;
person6 = (PersonN)malloc(sizeof(PersonN));
person6->firstName = (char*)malloc(sizeof(char) * );
strcpy(person6->firstName, "wu");
person6->lastName = (char*)malloc(sizeof(char) * );
strcpy(person6->lastName, "ba");
person6->title = (char*)malloc(sizeof(char) * );
strcpy(person6->title, "F");
person6->age = ; printf("The struct _person *person6 info:\n");
printf("person6->firstName: %s\n", person6->firstName);
printf("person6->lastName: %s\n", person6->lastName);
printf("person6->title: %s\n", person6->title);
printf("person6->age: %d\n", person6->age); free(person6->firstName);
free(person6->lastName);
free(person6->title);
free(person6); return ;
}
~
代码结果:
The struct _person *person1 info:
(*person1).firstName: zhang
(*person1).lastName: san
(*person1).title: A
(*person1).age:
The struct _person *person2 info:
person2->firstName: li
person2->lastName: si
person2->title: B
person2->age:
The struct _person *person3 info:
(*person3).firstName: wang
(*person3).lastName: wu
(*person3).title: C
(*person3).age:
The struct _person *person4 info:
person4->firstName: zhao
person4->lastName: liu
person4->title: D
person4->age:
The struct _person *person5 info:
(*person5).firstName: zhou
(*person5).lastName: qi
(*person5).title: E
(*person5).age:
The struct _person *person6 info:
person6->firstName: wu
person6->lastName: ba
person6->title: F
person6->age:
通过以上代码,相比阅读者对数据结构有了比较深刻的认识吧。有人可能会想到鲁迅笔下的孔乙己吧,这种做法会不会有茴香豆的茴字有四种写法的卖弄,如果这样想就错了,编程过程中,会碰到各种奇怪的应用场景,每一种用法都要学习点,以备不时之需吧。代码阅读完毕了,相比读者对使用->指针指向访问结构体指针的字段和使用(*).解引指针和成员运算符访问结构体指针的字段有了比较深入的理解了。
二、指针+和指针-:用于访问数组下表对应的内容,
1、定义:可以通过对指针进行简单的加减法,这点同普通变量一样,但是计算机的体现又是不一样的
2、特征:
1)、指针+和指针-的大小与加减的数值有关
2)、指针+和指针-的大小与指针的数据类型有关
3)、指针+和指针-的最终大小就是加减的数值与数据类型的大小的乘积
4)、不同的指针的指针+和指针-的大小是复杂的,要特别注意
5)、void类型的指针最好不要作加减操作
3、应用:
见如下代码:
代码如下:
1 #include <stdio.h>
2
3 int main(int argc, char **argv)
4 {
5 int iArray[] = {28, 32, 89, 77};
6 int *ptrArray = iArray;
7
8 //普通数组的访问
9 printf("The iArray:\n");
10 for(int i = 0; i < 4; i++){
11 printf("%d\t", iArray[i]);
12 }
13 printf("\n");
14
15 //普通数组的特殊访问
16 printf("The Other iArray:\n");
17 for(int i = 0; i < 4; i++){
18 printf("%d\t", i[iArray]);
19 }
20 printf("\n");
21
22 //普通数组的指针访问
23 printf("The Pointer+ iArray:\n");
24 for(int i = 0; i < 4; i++){
25 printf("%d\t", *ptrArray);
26 ptrArray += 1;
27 }
28 printf("\n");
29
30 printf("The Pointer- iArray:\n");
31 for(int i = 0; i < 4; i++){
32 ptrArray -= 1;
33 printf("%d\t", *ptrArray);
34 }
35 printf("\n");
36
37 return 0;
38 }
代码结果:
The iArray:
28 32 89 77
The Other iArray:
28 32 89 77
The Pointer+ iArray:
28 32 89 77
The Pointer- iArray:
77 89 32 28
代码中的26行使用了指针+操作,32行使用了指针-操作,由于指针是int型,因此,指针每增加或减少1,地址都会增加或减少整型数据的长度4。将指针值打印出来,在25行和33行下面增加如下:
printf("%p\t", ptrArray);
则代码结果为:
The iArray: The Other iArray: The Pointer+ iArray:
0x7ffd8b190ed0 0x7ffd8b190ed4 0x7ffd8b190ed8 0x7ffd8b190edc
The Pointer- iArray:
0x7ffd8b190edc 0x7ffd8b190ed8 0x7ffd8b190ed4 0x7ffd8b190ed0
三、指针相减和指针比较:主要是方便定位两个指针对应的数组元素的先后顺序,
1、定义:可以通过对指针进行简单的加减法,这点同普通变量一样,但是计算机的体现又是不一样的
2、特征:
1)、指针 - 指针的结果是两个地址的差值,利用该差值可以很容易判别数组中的元素的顺序
2)、指针+和指针-的大小与指针的数据类型有关
3)、指针与指针的比较确定指针对应数组元素的相对顺序
4)、指针相减的结果大于0表示前者指针的值大于后者指针
5)、指针比较的结果1为真,0为假
3、应用:
见如下代码:
代码如下:
#include <stdio.h> int main(int argc, char **argv)
{
int iArray[] = {, , , ,};
int *ptr0Array = iArray;
int *ptr1Array = iArray + ;
int *ptr2Array = iArray + ;
int *ptr3Array = iArray + ; printf("指针减法演示:\n");
printf("ptr3Array - ptr1Array: %d\n", ptr3Array - ptr1Array);
printf("ptr1Array - ptr3Array: %d\n", ptr1Array - ptr3Array); printf("指针比较演示:\n");
printf("ptr3Array > ptr1Array: %d\n", ptr3Array > ptr1Array);
printf("ptr1Array > ptr3Array: %d\n", ptr1Array > ptr3Array); return ;
}
代码结果:
指针减法演示:
ptr3Array - ptr1Array:
ptr1Array - ptr3Array: -
指针比较演示:
ptr3Array > ptr1Array:
ptr1Array > ptr3Array:
代码比较简单,就不再啰嗦了。
10深入理解C指针之---指针运算和比较的更多相关文章
- C 与 C++ 中 指向二维数组的指针进行指针运算
		
二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有"缝隙".以下面的二维数组 nums 为例: 从概念上理解,nums 的分布像一个矩阵,但在 ...
 - 娓娓道来c指针 (7)指针运算
		
(7)指针运算 在前几篇文章中,我们已经见过指针运算的使用场景,并多次使用指针运算来进行验证. 这里我们来特别地总结下.指针运算的本质含义. 在c语言中.如果p.pa.pb都是某种类型的指针,这种运算 ...
 - c#指针和寻址运算
		
一.指针和寻址运算 指针格式:<类型>*<变量> 寻址格式:&<变量> 以下程序的运行结果为 注意:每次运行程序时第一行显示的地址都不会一样. usin ...
 - 07深入理解C指针之---指针类型和长度
		
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 如果考虑到程序的可移植性和跨平台性时,指针长度就是一个问题,需要慎重处理.一般情况下, ...
 - 理解git 中的HEAD指针&branch指针
		
理解git 中的HEAD指针&branch指针 Yooye关注 2019.02.28 10:44:32字数 492阅读 668 HEAD指针 使用git checkout 来移动HEAD指针, ...
 - 深入理解C语言-二级指针三种内存模型
		
二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {&quo ...
 - 00深入理解C指针之--- 指针之外
		
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. C语言从诞生之初就非常善于和硬件打交道,经过这么多年的发展之后,其灵活性和超强的特征是 ...
 - 02深入理解C指针之---指针类型和值
		
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 1.指针的类型: 可以在声明指针时,指定指针的类型,例如: (1)void *x 声 ...
 - 06深入理解C指针之---指针操作和比较
		
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针作为一种特殊类型的变量,必须遵守C语言中变量先声明后使用的原则.本节内容中指针的操 ...
 
随机推荐
- cocos2dx for lua 简单的翻牌动画
			
local x = 20 local y = display.height/2 for i = 1,16 do--创建16张 local cardFg = display.newSprite(&quo ...
 - node中的定时任务
			
node-schedule每次都是通过新建一个scheduleJob对象来执行具体方法. 时间数值按下表表示 * * * * * * ┬ ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ | │ │ │ │ │ ...
 - 分享几个简单的技巧让你的 vue.js 代码更优雅
			
1. watch 与 computed 的巧妙结合 一个简单的列表页面. 你可能会这么做: created(){ this.fetchData() }, watch: { keyword(){ thi ...
 - mysql的字符串连接符
			
以前用SQL Server 连接字符串是用“+”,现在数据库用mysql,写个累加两个字段值SQL语句居然不支持"+",郁闷了半天在网上查下,才知道mysql里的+是数字相加的操作 ...
 - 编译与安装 OpenSSL
			
编译与安装 OpenSSL prefix 是安装目录,openssldir 是配置文件目录,另外建议安装两次,shared 作用是生成动态连接库.linux版的OpenSSL下载地址为:https:/ ...
 - Python学习笔记:open函数和with临时运行环境(文件操作)
			
open函数 1.open函数: file=open(filename, encoding='utf-8'),open()函数是Python内置的用于对文件的读写操作,返回的是文件的流对象(而不是文件 ...
 - leetcode-16-greedyAlgorithm
			
455. Assign Cookies 解题思路: 先将两个数组按升序排序,然后从后往前遍历,当s[j] >= g[i]的时候,就把s[j]分给g[i],i,j都向前移动,count+1;否则向 ...
 - SPOJ QTREE6 Query on a tree VI 树链剖分
			
题意: 给出一棵含有\(n(1 \leq n \leq 10^5)\)个节点的树,每个顶点只有两种颜色:黑色和白色. 一开始所有的点都是黑色,下面有两种共\(m(1 \leq n \leq 10^5) ...
 - LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用
			
延迟执行的经典例子: 我们用 select ++i 就可以看到在foreach 时候,查询才被执行. public static void Linq99(){ int[] numbers = n ...
 - Python学习——第一天
			
https://www.runoob.com/python/python-chinese-encoding.html 第一个python程序 [root@mini1 ~]# vi python01.p ...