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语言中变量先声明后使用的原则.本节内容中指针的操 ...
随机推荐
- ios sinaweibo 客户端(二)
这一篇博文讲述发微博界面的实现. 首先我们先了解一下在这个发微博界面中需要做哪些事情吧! (1) 发微博包括文字内容和微博图片,所以我们可以用一个textview来装载微博文字内容,用一个imagev ...
- XAMPP vhost 配置(403问题解决)
<VirtualHost *:80> DocumentRoot "C:/xampp/htdocs/" ServerName localhost </Virtual ...
- C语言输出多位小数
#include<stdio.h>#include<stdlib.h>int main(){int i=0;int m=19;int n=3;int s=0;s=m/n;pri ...
- HDU-4848-Such Conquering
这题就是深搜加剪枝,有一个很明显的剪枝,因为题目中给出了一个deadline,所以我们一定要用这个deadline来进行剪枝. 题目的意思是求到达每个点的时间总和,当时把题看错了,卡了好久. 剪枝一: ...
- 13Shell脚本—编写简单脚本
1. 概述 Shell脚本命令的工作方式有两种:交互式和批处理. 交互式(Interrctive): 用户每输入一条命令就立即执行. 批处理(Batch): 由用户事先编写好一个完整的 Shell 脚 ...
- 动态设置html的title
使用vue前端框架做,竟然丢弃了很多javascript和html的东西了..动态设置title的方法: 1.使用vue的自定义指令 <div v-title>{{htmltitle}}& ...
- 【nginx】nginx.sh nginx 安装脚本
#! /bin/shcd /usr/local/srcwget http://nginx.org/download/nginx-1.10.1.tar.gzecho 'download success' ...
- [译]The Python Tutorial#8. Errors and Exceptions
[译]The Python Tutorial#Errors and Exceptions 到现在为止都没有过多介绍错误信息,但是已经在一些示例中使用过错误信息.Python至少有两种类型的错误:语法错 ...
- luogu3369 【模板】普通平衡树(Treap/SBT) treap splay
treap做法,参考hzwer的博客 #include <iostream> #include <cstdlib> #include <cstdio> using ...
- Just a test