C语言基础 (四)指针与数组
来源:互联网 发布:淘宝联盟返现 编辑:程序博客网 时间:2024/05/17 03:55
数据保存在内存中,而每一块内存空间都有一个编号,称为内存地址。
指针变量用来存放这个地址编号的变量称为指针变量;
通过指针可以访问和处理指针所指向的对象,增加了访问数据的手段,使程序更加灵活。
指针本身也是一个变量,它存储的是另一个变量的地址。存放变量地址的变量是指针变量。因此,一个指针变量的值就是某个变量的地址。为了表示指针和他所指向的变量之间关系,在程序中用*符号表示指向。
在32位系统中,指针变量都是占4个字节,64位系统占8个字节。指针变量中保存的只是地址编号,不管是什么类型的指针保存的都是地址编号。所以同一系统中什么类型的指针变量都是占相同的字节数。
打印地址编号%d输出的是十进制的地址 %p输出的是16进制的地址。
指针变量的四个特点
1、 它的值就是一个地址
2、 指针变量的值可以改变,存储一个新的地址,即指向别的变量;
3、 指针指向一个特定的类型,即指针本身也是有类型的。
4、 多个指针变量可以指向同一个值。
int a=5; int *p=&a; //在声明指针时,*放在类型后边,表示变量是指针变量。 *p=100; //p是a的地址,*p就是a //int*q=100; //q指向地址编号为100 的存储单元,这是一种错误的写法 *p =*p * *p; *p--; //* ++的优先级一样,结合性是从右到左,所以p会进行++就不再指向a printf("%d\n",a); //通过变量a访问数据5 printf("%d\n",*p); //指针前加* 表示对指针的解引用,即访问指针指向的变量; //在声明之外的地方,*表示对指针解引用;声明指针变量 char *p int *p flaot * p 等等;野指针 int a=5; int *p;//没有初始化的指针,叫做野指针,即指针指向不明确的指针*p=100;//指针的指向不明确,就不能解引用。必须先有地址再赋值;空指针 int*q=NULL;//NULL表示空 被初始化成null的指针叫空指针,指向内存编号为0的内存 //空指针也不可以解引用空指针与野指针的区别:野指针:未被初始化的指针,里面的内容是垃圾地址,它的值是不明确的;空指针:被初始化的指针,里面的地址是0;注意不要解引用空指针和野指针 int a=5; int b=10; int *p; p=&a; //p本身的值是a的地址,p指向a p=&b; //修改p本身的值,存储一个新的地址,即指向新的变量,p指向bprintf("%d",*p); //指针本身也是有类型的。要指向特定类型的变量。 int a=5; int *p=&a; //在声明指针时,*放在类型后边,表示变量是指针变量。 *p=100; //p是a的地址,*p就是a //int*q=100; //q指向地址编号为100 的存储单元,这是一种错误的写法 *p =*p * *p; *p--; //* ++的优先级一样,结合性是从右到左,所以p会进行++就不再指向a printf("%d\n",a); //通过变量a访问数据5 printf("%d\n",*p); //指针前加* 表示对指针的解引用,即访问指针指向的变量; //在声明之外的地方,*表示对指针解引用; int a=5; int *p; //没有初始化的指针,叫做野指针,即指针指向不明确的指针 *p=100; //指针的指向不明确,就不能解引用。 int *q=NULL;printf("%d",*q); // 空指针不能解引用void change(int *x,int *y){ //参数是传一个指针变量。 int temp=0; //通过解引用交换,变量的值; if (*x < *y) { temp=*x; *x=*y; *y=temp; }//通过数组名地址,打印数组元素void pfarray(){ int a[5]; for (int i=0; i<5; i++) { scanf("%d",&a[i]); } for (int k=0; k<5;k++) { printf("%d",*(a+k)); a+k就是第k个元素的地址 }}void exchange(int *p,int *q){//相当于 int temp=*p; //temp=a; *p=*q; //a=b; *q=temp; //b=temp}//修改形参不会影响实参 在传值,传指针时,都适用void changebyad(int *p,int *q){ int *temp=p; p=q; q=temp; //在函数中只交换了形参p和q的指向,并没有修改p和q指向的变量 printf("&p=%p &q=%p\n",p,q ); //并不能实现值的交换}int *max(int ,int);#include <stdio.h>int main(){ int a=5; int b=10; int *r=max(a,b); printf("%d",*r); //虽然也可以返回正确的值,但是不能这么用}int *max(int x,int y){//x,y是max函数的形参,只存在函数中,函数执行结束,p和q就会释放掉; return x>y? &x:&y;//不要返回局部变量的地址,当局部变量的地址释放掉之后,指针就变成了野指针}#include <stdio.h>int main(){ int a=5; int *p=&a;//p中保存的是a的地址 //指针变量也是一个变量,本身也有地址 int **q=&p; // 保存一维指针地址的指针称为二维指针 //**q是二维指针。 printf("%d\n",a); printf("%d\n",*p); printf("%d\n",**q); //q-->&p 关于指针要记住两个值 //*q-->p 1、指针本身的值 //**q-->*p 2、指针加* 的值 return 0;}void exchage (int **x,int **y){//利用二维指针进行地址的交换 int *temp=*x; //temp=p; *x=*y; //p=q; *y=temp; //q=temp;} 指针和数组 int a[5]={1,2,3,4,5}; printf("%p\n",&a[0]); //结果为0x7fff5fbff7b0 printf("%p\n",a); //结果为0x7fff5fbff7b0 //数组名a是数组中首元素的地址,即a【0】的地址 //数组名a是指向数组首元素的指针 int *p=a; // p的值就是数组首元素的地址 //a=&a[1] 这样写是错的,a的值不能变,只能指向数组中的首元素。 printf("%p\n",p); printf("%p\n",&a[1]); printf("%p\n",&a[2]);return 0;int a[5]={1,2,3,4,5};int *p=a; //printf("%p %p\n",&a[1],(p+1)); //首元素地址加1就是第二个元素的地址 //首元素地址加n就是第n+1个元素的地址(下标为n的元素的地址)// for (int i=0; i<5;i++) {// printf("%d\t",*(p+i));//p+i就是下标为i的元素的地址// } for (int k=0; k<5; k++) { printf("%d\n",*(p+k));//指针加1并不是地址加1而是偏移一个元素 } for ( p=a; p<=&a[4]; p++) { printf("%d\t",*p); } printf("\n"); p--;//指针加1,指向后边一个元素,指针减1,指向前边一个元素(就算不是数组也能指回去) printf("%d",*p);} int a[5]={1,2,3,4,5}; int *p=a; fun1(p); printf("%d\n",*p); for (int k=0; k<5; k++) { printf("%d",*(p+k)); }} void fun(int *q){ (*q)++; }void fun1(int *q){ q++; //只修改形参,不是影响实参 (*q)++; // 第二个元素的值会加1;}//通过使用二维指针修改 指针变量m中的值,改变指针变量m的指向void fun2(int **x);void fun(int *x);int main(){ int a[5]={1,3,5,6,7}; int *m=a; for (int i=0; i<5; i++) { fun(m); //使元素的值加1; fun2(&m); //指针变量m指向的元素一次向后加1 } for (int k=0;k<5; k++) { printf("%d",a[k]) ; } printf("\n");}void fun2(int **x){ (*x)++; //*x就是指针变量m中存放的值即数组a的首地址 然后进行加加操作就指 } //向了数组中的下一个元素void fun(int *x){ (*x)++; //*x就是*p 指向数组中元素的值,首元素执行 ++ 操作}内存分配局部变量,在函数中或某个程序块中声明的变量叫做局部变量。全局变量 在所有的函数的外边声明的变量叫做全局变量 int main(){ int a=5; //该变量是局部变量,所在的内存区是在栈上 int *p=&a; //p也是局部变量,也在栈上 const int b=10; //b是常量,在常量区; //栈上的空间有程序自动分配和释放void *malloc(size_t size); //不是空,是一个没有类型的指针,在堆区请求一块存储空间,size请求空间大小,malloc返回这个指针指向请求的堆空间,如果请求失败,则返回null;int main(){ int a=5; int *p=&a; int *q=(int *)malloc(4);//在堆区分配4个字节的空间,将该空间的地址返回值赋值给指针q; //这块空间没有名字,只能通过这块空间的地址去访问 *q=100; printf("%d\n",*q);//q是栈上的指针保存堆空间的地址 float *pf=(float *)malloc(4); *pf=5.9; printf("%f\n",*pf); free(q); free(pf);//释放堆空间 空间指正释放一次,不能重复释放。释放掉之后就不要再访问了。 printf("%f\n",*pf);//释放后仍能被打印出来 //每个存储单元都有两个状态,一个占用状态,一个空闲状态 //分配空间就是把这块空间由空闲状态标记为占用状态,释放空间,就是把这块空间由占用状态标记为空闲状态,并没有抹掉这块空间的内容。 //p的值一直没有改变,空间释放后依然指向这块空间,变成野指针了。通过指针还可以继续访问这块空间 return 0;常量指针,指向常量的指针,指针本身的值可以修改,但指针加* 的值不能修改。//指针常量 指针本省是个常量,指针本身的值不能改,但指针加*的值可以改。//const 修饰谁,谁就不能变const int *p修饰的是*则指向的变量的值不能变//int *const p修饰的是p则p的值不能改变即存的地址不能改变;//int main(){// int a=10;// int b=20;// const int *p=&a;// int* const q=&b;// p=&b;// // *p=100;//}//引用 常量引用//j的值不可以修改,i的值可以修改。传值:形参是实参的值的拷贝,形参的改变不会影响实参,单向传递。传指针:也是传值的一种方式,是通过形参简洁改变实参所指向的变量的值传应用:形参就是实参,改变形参就是改变实参,双向传递。局部变量和全局变量重名,全局变量会被隐藏,通过::作用域符号访问该全局变量引用定义已定义的全局变量 extern
阅读全文
0 0
- C语言基础 (四)指针与数组
- C语言基础(四)指针 数组
- C语言数组与指针(四)
- c语言基础—指针与数组
- C语言基础-指针与数组
- C语言基础 指针与数组
- C语言基础之指针与数组
- C语言基础(四)(指针)
- c语言基础(四)之指针
- 【C语言复习(四)】指针基础
- c语言基础(四)指针篇
- C语言基础四(指针)
- C++预科——C语言指针回顾(四) 指针与数组之间的关系
- c语言基础:数组、指针
- c语言基础--数组指针
- C语言:指针数组与数组指针
- C语言指针数组与数组指针
- C语言指针数组与数组指针
- oracle ITL(事务槽)的理解
- heartbeat高可用+lvs负载均衡
- 为圆角矩形卡片底部添加阴影效果
- CSU-ACM2017暑期训练3-递推与递归 G
- String--每日一练(Reverse Words in a String III)
- C语言基础 (四)指针与数组
- (Kattis
- hdu2044 一只小蜜蜂
- Python 循环嵌套
- 欢迎使用CSDN-markdown编辑器
- 错误与调试
- 子数组之和-LintCode
- 空间换时间小例子(2)
- HDU