A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 曦正 中级黑马   /  2016-2-20 18:37  /  480 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

发现上传了一个指针与数组的关系,却没有上传指针
补上
——————————————————————————
——————————分割线—————————————
——————————————————————————
什么是地址?就是一个位置(坐标、门牌号。。。 。。。)

指针类型

***指针就是一个存储其它变量地址的变量;***
C语言的指针类型包括两方面的信息:
1.是地址,存放在指针变量中;
2.是类型信息,关乎于读写的长度,没有存储在指针变量中,位于用该指针读写时的mov指令中,不同的读写长度对应的mov指令不同,指针存储了内存的地址。
同时,指针是有类型的,如 int、 float、*char,那么,一个自然的猜想就是指针变量应该存储这两方面的信息地址和指针类型,例如:

mov指令是汇编语言中的指令,指的是数据的传送;也就是说指针只存放变量的地址和类型,而mov才是存放数据的值;(所以才有不同读写长度对应的mov指令不同);
struct pointer{
    long address;
    int type;
}
语法格式:
type pointer;
int ip;
char cp;
student sp;
指针运算符“*”:取出指针所指位置的数据;
取地址运算符“&”:得到变量所在的内存位置,即其内存地址;
例如:

int c=8;
int *i=&c;
printf("%d\n",*i); //*i指向变量c的内容
printf("%p\n",i);//i指向的是变量c的地址
也就是说,可以通过变量ip去寻找c的地址,再通过指针*取变量c的内容;
指针之间的赋值

int i=100;
int *ip=&i;
int *iq;
iq=ip;//ip和iq指向同一内存单元
printf("*ip==%d——*iq==%d\n",*ip,*iq);
//此时取ip指向的值与iq指向的值都是指向变量 i=100的地址
如何定义一个指针?

#include <stdio.h>
int main(int argc,const char* argv[]){
int a;
int *p=&a;//把a的地址赋给p,p——>&a
//把变量名换成指针名,在前面+*,就是指向变量地址的指针了
printf("%d\n",*p);//取存在p中的地址的值
return 0;
}
#include <stdio.h>
int main(int argc,const char* argv[]){
int *arr[4][3];
int *(*parr)[4][3]=&arr;//把a的地址赋给p,parr——>&arr
//把变量名换成指针名,在前面+*,就是指向变量地址的指针了
return 0;
}
指针运算

如何取值?使用“*”运算符,如:

#include <stdio.h>
int main(int argc,const char* argv[]){
int a=100;
int *p=&a;//把变量a的地址存到指针变量p中
printf("%d\n",*p);//从指针变量p中取取出指向地址中的那个值
return 0;
}
指针的运算:指针可以进行赋值运算、关系运算、算数运算;
指针+1:表示向高位移动一步,这一步表示时当前指针类型所占的字节数;
指针-1:表示向低位移动一步,这一步表示时当前指针类型所占的字节数;

#include <stdio.h>
int main(int argc,const char* argv[]){
int a=100;
int b=200;
int c=300;
int *pa=&a;
int *pb=&b;
int *pc=&c;
printf("%d\n",*(pb));
//取pb指向的地址里存的那个值;
printf("%d\n",*(pb+1));
//取pb指向的地址向上跨越了1个int的字节数,等效于*pa;
printf("%d\n",*(pb-1));
//取pb指向的地址向下跨越1个int的字节数,等效于*pc;
return 0;
}
指针强转

由于指针移动没有限制,可以在内存中随意移动,所以要格外小心,指针移动之后,用*指针获取值时,要获取几个字节的数据,看当前这个指针是什么类型的,就获取多少个字节的数据,同时用这个类型的变量去接收;

指针与数组

指针数组与数组指针
指针数组:本质上是数组,数组元素是指针;
数组指针:本质上是指针,指针指向的是数组的地址;
数组指针与数组元素的指针

数组指针

int arr[3]={1,2,3};
int * parr[3]=&arr;//称parr为arr整个数组的指针
for(int i=0;i<3;i++){
printf("%d\n",*(parr+i));//获取parr跨越i个元素的值,等效于arr[i];
}
int *ptemp=&arr[0];
/*常用int *ptemp=arr,因为arr本身包含首元素的地址;
数组名当参数传递是,,所传递的是其首元素的地址,所以数组当参数传递时,无法通过sizeof计算出数组长度;
*/
void test(int* a){
for(int i=0;i<3;i++){
printf("%d\n",a[i]);
}
int main(int argc,const char* argv[]){
int arr[3]={1,2,3};
test(arr);
指针数组

#include <stdio.h>
int main(int argc,const char* atgv[]){
int a=100,b=200;
int *pa=&a;
int *pb=&b;
int *arr[2]={pa,pb};
//指针数组里面的元素是指针,pa是指向a的指针,pb是指向b的指针;
//*arr[i]就是取数组里第i个元素所指向的地址的值;
for(int i=0;i<2;i++){
printf("%d\n",*arr[i]);
}
return 0;
}
指针与字符串

用字符指针可以表示一个字符串,如:

char * str="abc";
//str指向字符串中第0个字符的地址
//重新赋值
str="bcd";
指针与结构体

一个指针指向的是一个结构体,其里面存储的是一个结构体的地址;
唯一注意的是:结构体指针去取结构体元素时,可以用指针名——>元素名,如:

struct person{
char* name;
int age;
};
struct person per={"李四",20};
struct person *p=&per;
p-->name;
指针与函数

函数可以用指针当参数传递,函数的参数类型不可以是函数,但可以是指针;

void test(void(*p)int *arr,int length);
int main(int argc,const char* argv[]){
void(*p)(int *arr,int length)=test2;
test(test2);
}
把一个函数取赋值给一个函数指针时,这个指针可以作为别的函数的参数,函数指针的变量名可以当参数使用;
函数指针的定义方式:
把函数的声明原封不动拷贝下来,然后把函数名换成指针名,前面+*;
取值时,指针变量名==函数名,不需要+&;
指针型函数:
返回值是指针的函数;
注意:只能是基本类型的指针;

指针与指针

一个指针指向另一个指针(存的是另一个指针变量的地址);

#include <stdio.h>
int main(int argc,const char* argv[]){
    int a=100;
    int *p=&a;//p等效于a的地址,*p就是取a地址中的值
    int **p1=&p;//p1等效于p的地址,*p1就是取p地址中的值,也就是a的地址,*p1==p
    int ***p2=&p1;//p2等效于p1的地址,*p2就是取p1地址中的值,也就是p的地址,**p2==p
    int ****p3=&p2;//p3等效于p2点地址,*p3就是取p2地址中的值,也就是p1的地址,***p3==p;
//以下打印的全都是变量a的值
    printf("*p==%d\n",*p);
    printf("**p1==%d\n",**p1);
    printf("***p2==%d\n",***p2);
    printf("****p3==%d\n",****p3);
return 0;
}
——————————————————————————————
——————————————————————————————
如果有错漏的希望能够进行补充指正,谢谢!!

评分

参与人数 1黑马币 +3 收起 理由
w83144378 + 3 很给力!

查看全部评分

1 个回复

正序浏览
写的很好  copy一份
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马