企业如何建官方网站,扬州seo优化,asp.net做网站头部和尾部_都用什么来实现,seo定义指针是C语言的核心、精髓所在#xff0c;用好了指针可以在C语言编程中起到事半功倍的效果。指针一方面可以提高程序的编译效率和执行速度#xff0c;而且还可以通过指针实现动态的存储分配#xff0c;另一方面使用指针可使程序更灵活#xff0c;便于表示各种数据结构#… 指针是C语言的核心、精髓所在用好了指针可以在C语言编程中起到事半功倍的效果。指针一方面可以提高程序的编译效率和执行速度而且还可以通过指针实现动态的存储分配另一方面使用指针可使程序更灵活便于表示各种数据结构编写高质量的程序。同时其抽象概念学习过程中要多看多练使用时应多注意否则操作不当会导致整个程序收到破坏。
1 指针相关概念 指针是C语言最显著的优点之一指针使用起来十分灵活而且能提高某些程序的效率但是指针使用不当会很容易造成系统错误往往许多程序“挂死”的大部分原因都是错误地使用指针所造成的。
1.1 地址与指针 系统的内存就像带有编号的房间如果想使用内存就需要得到房间编号。例如定义一个整型变量i,整型变量需要4个字节所以编译器为变量i分配编号从1000~1003。 什么是地址地址就是内存区中对每个字节的编号例如上面的1000~1003就是地址。 什么是指针这里仅把指针看作是内存的一个地址多数情况下这个地址是内存中另一个变量的位置如下图 上图中定义了一个变量在进行编译时就会给这个变量在内存中分配一个地址通过访问这个地址就可以找到所需的变量该变量的地址称为该变量的指针。上图中的地址1000就是变量i的指针。
【说明】在C语言中存取变量值的方法有两种。按变量地址存取变量的方式称为“直接访问”将变量地址存放在另一个变量中先找到存放“变量地址”的另一个变量通过另一个变量找到变量的地址这种方法称为“间接访问”。
1.2 指针变量
1.2.1 变量与指针 变量的地址是变量和指针两者之间连接的纽带如果一个变量包含了另一个变量的地址那么第一个变量可以说成是指向第二个变量。所谓“指向”就是通过地址来体现的在程序中用“*”表示指向。因为指针变量是指向一个变量的地址所以将一个变量的地址值赋给这个指针变量后这个指针变量就“指向”了该变量。例如将变量i地址存放到指针变量p中p就指向i。在程序代码中是通过变量名来对内存单元进行存取操作的但是代码经过编译后已经将变量名转换成该变量在内存的存放地址对变量值的存取都是通过地址进行的。例如对变量i和j进行如下操作 int i,j;i j; 其含义根据变量名与地址的对应关系找到变量i的地址1000然后从1000开始读取4个字节数据放到CPU寄存器中在找到变量j的地址1004从1004开始读取4个字节的数据放到CPU的另一个寄存器中通过CPU计算出结果。
1.2.2 使用指针变量 由于通过地址能访问指定的内存存储单元可以说是地址“指向”该内存单元。地址可以称之为指针意思是通过指针就能找到内存单元。一个变量的地址称为该变量的指针。如果有一个变量专门用来存放另一个变量的地址它就是指针变量。在C语言中有专门用来存放内存单元地址的变量类型就是指针类型。 指针变量的一般形式类型说明 * 变量名。其中*表示这是一个指针变量变量名即为定义的指针变量名类型说明本指针变量所指向的变量的数据类型。 指针变量的赋值指针变量同普通变量一样使用之前不仅要定义而且必须赋予具体的值。未经赋值的指针变量不能使用。给指针变量所赋的值与给其他变量所赋的值不同给指针变量的赋值只能赋予地址而不能赋予任何其他数据否则将引起错误。C语言提供了地址运算符“”来表示变量的地址。一般形式为 变量名。例如a表示变量a的地址b表示变量b的地址。给一个指针变量赋值可以有两种方法。 1、定义指针变量的同时进行赋值int aint *p a 2、先定义指针变量之后在赋值int aint *p p a 【注意】两者的区别如果在定义完指针变量之后再赋值注意不要加*。 【示例1】利用指针输出数据。 #include stdio.h
int main(){int a,b;//声明两个指针变量int *ip1,*ip2;printf(请输入苹果和香蕉的价格 \n);scanf(%d,%d,a,b);ip1 a;ip2 b;printf(苹果的价格是: %d/一斤 \n,*ip1);printf(香蕉的价格是%d/一斤 \n,*ip2);return 0;
} 指针变量的引用 引用指针变量是对变量进行间接访问的一种形式。对指针变量的引用形式如下 * 指针变量。其含义是引用指针变量所指向的值。 【示例2】利用指针变量实现数据的输入、输出。
#include stdio.h
int main(){int *p,q;printf(请输入香蕉的价格: \n);scanf(%d,q);p q;printf(香蕉的价格是%d 元一斤\n,*p);return 0;
} 1.3 和 * 运算符 上面介绍指针变量的过程中用到了两个运算符 和 * 是一个返回操作数地址的单目运算符叫做取地址运算符例如p a。就是把变量a的内存地址赋给p这个地址是该变量在计算机内部存储的地址。 * 是单目运算符叫做指针运算符作用是返回指定地址内变量的值如上面提到的p中装有变量a的内存地址则 q *p。就是把变量a的值赋给q假如a 5那么q 5. 指针运算符和取地址运算符可以组合使用那么*和*有什么区别呢有如下语句
int a;
p a; 通过以上两个语句来发分析 * 和 * 之间的区别和*的运算符优先级别相同按自右而左的方向结合。因此*先计算*运算*p相当于变量a再进行运算*p就相当于取变量a的地址。*a先计算运算a就是取变量a的地址再进行*计算*a相当于取变量a所在地址的值实际就是a变量。
【示例1】 * 应用。
#include stdio.hint main(int argc, const char * argv[]) {long i;long *p;printf(请输入一个数值\n);scanf(%ld,i);p i;printf(输出*p结果是%ld\n,*p);printf(输出i结果是%ld\n,i);return 0;
} 【示例2】* 应用
#include stdio.hint main(int argc, const char * argv[]) {long i, *p;printf(请输入一个数值\n);scanf(%ld,i);p i;printf(输出*i的结果是%ld\n,*i);printf(输出i的结果是%ld\n,i);printf(输出*p的结果是%ld\n,*p);return 0;
}其中示例1*p和i的作用相同都是取变量i的地址 。 示例2*p和*p相同取变量的值。
1.4 指针的算术运算 指针有加减两种运算即指针的自加和自减这不同于普通变量的自加自减运算并不是简单的加1或减1。
【示例1】整型变量地址输出
#include stdio.hint main(int argc, const char * argv[]) {int i;int *p;printf(请输入一个数值\n);scanf(%d,i);p i;printf(p的结果是%d\n,p);p;printf(p的结果是%d\n,p);return 0;
} 把上面代码的变量修改为short变量再次执行。
#include stdio.hint main(int argc, const char * argv[]) {short i;short *p;printf(请输入一个数值\n);scanf(%d,i);p i;printf(p的结果是%d\n,p);p;printf(p的结果是%d\n,p);return 0;
} 从两个示例可以看出这里的指针自加不是简单的在地址上加1而是指向下一个存放基本整型数的地址第一个示例的变量是基本整型所以p后p的值增加4基本整型占4个字节第二个示例的变量定义为短整型所以p后p的值加2短整型占2个字节。 【结论】 指针都是按照它所指向的数据类型的直接长度进行加减的。
【范例1】转向的指针通过交换两个指针变量的值取改变指针的方向。
#include stdio.hint main(void) {int *p1,*p2,a,b,*t;printf(请输入a,b的值\n);scanf(%d,%d,a,b);p1 a;p2 b;if(*p1 *p2){t p1;p1 p2;p2 t;}printf(%d %d\n,*p1,*p2);return 0;
} 2 一维数组与指针 数组在内存中存放也同样具有地址。 对于数组来说数据名就是数组在内存中存储的首地址。指针变量用于存放变量的地址自然也可以存放数组的首地址或数组元素的地址这样就给数组和指针之间建立了一个联系。
2.1 指向数组元素的指针 当定义了一个一维数组时系统会在内存中为该数组分配一个存储空间。其数组的名字就是数组在内存的首地址。如果在定义一个指针变量并将数组的首地址传给指针变量则该指针就指向了这个一维数组。如int *p,a[10]; p a; 这里a是数组名也就是数组的首地址将它赋给指针变量p也就是将数组a的首地址赋给p也可以写成int *p,a[10]; p a[0]。
【注意】在将数组名赋给指针变量时不需要写“”但是将数组首地址赋给指针变量时需要加上“”。
【示例2.1.1】输出数组的元素。
#include stdio.hint main(void) {int *p,*q,a[5],b[5],i;p a[0];q b;printf(请输入数组a中的元素:\n);for(i 0;i5;i){scanf(%d,a[i]);}printf(请输入数组b中的元素\n);for(i 0;i5;i){scanf(%d,b[i]);}printf(数组a的元素是\n);for(i 0;i5;i){printf(%5d,*(pi));}printf(\n);printf(数组b的元素是“\n);for( i 0;i5;i){printf(%5d,*(qi));}printf(\n);
}2.2 使用指针访问数组 对于一维数组的引用有两种方法一种是下标法另一种是指针法。下标法是采用a[i]的形式引用数组中的元素而指针法时本篇主要介绍的首先看下面两条语句int *p,a[10]; p a; 上面的语句将作以下几方面介绍 1、p n 与 a n表示数组元素a[n]的地址即a[n]。对整个a数组来说共有10个元素n的取值是0~9则数组元素的地址就可以表示为p0~p9或者a0~a9如下图 2、如何来表示数组中的元素用到了前面介绍的数组元素的地址用*(pn)和*(an)来表示数组中的各个元素。例如下面的语句printf(%10d,*(pi)) ;printf(%10d,*(qi))分别表示输出数组a和数组b中对应的元素。 上面提到可以用an表示数组元素的地址*(an)表示数组元素那么就可以把上面的程序进行改造
#include stdio.hint main(void) {int *p,*q,a[5],b[5],i;p a[0];q b;printf(请输入数组a中的元素:\n);for(i 0;i5;i){scanf(%d,a[i]);}printf(请输入数组b中的元素\n);for(i 0;i5;i){scanf(%d,b[i]);}printf(数组a的元素是\n);for(i 0;i5;i){printf(%5d,*(ai));}printf(\n);printf(数组b的元素是“\n);for( i 0;i5;i){printf(%5d,*(bi));}printf(\n);
} 3、表示指针的移动可以使用”“和”--“运算符利用”“运算符可以把上面的程序再次改造 #include stdio.hint main(void) {int *p,*q,a[5],b[5],i;p a[0];q b;printf(请输入数组a中的元素:\n);for(i 0;i5;i){scanf(%d,p);}printf(请输入数组b中的元素\n);for(i 0;i5;i){scanf(%d,q);}p a;q b;printf(数组a的元素是\n);for(i 0;i5;i){printf(%5d,*p);}printf(\n);printf(数组b的元素是“\n);for( i 0;i5;i){printf(%5d,*q);}printf(\n);
} 【示例2.1】查找数列中的最值。输入10个整型数字自动查找这些数中的最大值和最小值。
#include stdio.h
void max_min(int a[],int n,int *max,int *min){int *p;*max *min *a;for(p a 1;p a n; p ){if(*p *max){*max *p;}else if(*p *min){*min *p;}}
}int main(void) {int i,a[10];int max,min;printf(请输入10个整数:\n);for(i 0;i10;i){scanf(%d,a[i]);}max_min(a,10,max,min);printf(最大值是:%d\n,max);printf(最小值是%d\n,min);getchar();} 3 字符串与指针 字符串常量是由双引号组成的字符序列表示字符串可以用字符数组即通过数组名来表示字符串数组名就是数组的首地址是字符串的起始地址。现在将字符串数组的名赋予一个指向字符类型的指针变量让字符类型指针指向字符串在内存的首地址对字符串的表示就可以用指针实现。
3.1 字符型指针 字符型指针就是指向字符型内存空间的指针变量一般形式为char *p 使用字符型指针可以访问字符串。
【示例3.1】字符型指针
#include stdio.hint main(int argc, const char * argv[]) {char *string 生当作人杰死亦为鬼雄\n;printf(%s\n,string);return 0;
}【示例3.1.1】声明两个字符数组将str1中的字符串复制到str2中
#include stdio.hint main(int argc, const char * argv[]) {char str1[]生当作人杰死亦为鬼雄,str2[15],*p1,*p2;p1 str1;p2 str2;while(*p1 ! \0){*p2 *p1;p1 ;p2 ;}*p2 \0;printf(第二个字符串的内容是:\n);puts(str2);return 0;
} 3.2 字符串数组 这里提到的字符串数组与前面提到的字符数组不同字符数组是一个一维数组而字符串数组是以字符串作为数组元素的数组可以将其看成一个二维字符数组。例如下面一个简单的字符串数组定义
char country[5][20] {中国,美国,俄罗斯,英国,法国} 字符型数组变量country被定义为含有5个字符串的数组每个字符串的长度要小于20(要考虑字符串最后的\0)。通过观察上面定义的字符串数组会发现元素的长度远远小于其定义的20个字节的空间这样会造成空间浪费。为了解决这个问题可以使用指针数组每个指针指向所需要的字符常量这种方法虽然需要再数组中保存字符指针同样也占用空间但要远少于字符串数组所需要的空间。 那么什么是指针数组呢一个数组其元素均为指针类型数据成为指针数组。也就是说指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义形式
类型名 数组名[数组长度] 【例3.2.1】输出一周7天
#include stdio.hint main() {int i;char *month[] {星期一,星期二,星期三,星期四,星期五,星期六,星期日};for(i 0;i7;i){printf(%s \n,month[i]);}return 0;}