您的位置:首页 > 编程语言 > C语言/C++

黑马程序员------C语言程序 指针

2015-07-23 21:20 253 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、指针

1,指针变量概念机定义方法

指针变量: 在c语言中,允许用一个变量来存放指针,这种变量称为指针。

严格意义说,指针式一个地址,是一个常量,指针变量事存放一个地址,事一个变量

2定义一个指针变量

指针类型说明,即定义变量为一个指针变量;

指针变量名

指针值(指针)

一般形式 类型说明符 *变量名

int *p 定义了一个指针变量,变量名是p

int,表示p只能存放一个int 类型的变量的地址

3指针变量的定义的注意:

1"*" 必须得有如果没有就相当于定义一个普通变量

2指针变量 不能 用来存放数值或者名符之类

3指针变量,归根到底还是变量也有全局变量和局部变量之分

4指针变量的初始化

指针变量也是变量

指针变量的使用:定义指针变量 》初始化指针变量》使用

完全初始化

1)定义的同时初始化

int *p =&a ;

2)部分初始化

int *p=&b,*P4;

p4=&c;

2)定义后初始化

int *p2;

p2 =NULL; //是空

3)定义了一个指针变量,不知道指向谁

int *P8=NULL;

int *p6 = 0; //把一个指针定义为空,就是什么也不指向。

指针变量的作用:获取指针变量指向的内存空间的内容

获取指针变量值所对应的存储单元

”*“ 的两种用法

1用来定义一个指针变量

2获取值 *p 获取p指向的变量地址的值

4)指针变量不初始化有什么后果

如果不初始化 这个指针变量放的就是垃圾值,这个指针就叫野指针。

5.用函数交换两个变量的值

void swap(int a,int b){

int temp=0;

tmp =a

a=b;

b=temp;

} 在函数中这个只是函数的形参变了

正确的是用指针

#include <stdio.h>
void swap1(int*p,int*p1){
int *temp;
temp =p;
p=p1;
p1=temp;
}

int main(int argc,const char *argv){
int a=a4,b=5;
printf("交换前a=%d,b=%d\n",a,b);
swap1(&a,&b);
printf("交换后的值 a=%d, b=%d\n",a,b)
return 0;
}

7,指针的应用场景

1)在被函数中可以修改主函数中的变量之值。

void changValue(int*p){

*p =10;

}

int main( int argc ,const char*argv[]){

int a=10;

int *P1 =&a //p1指向了a

printf("%d\n",*p1);//a=10

change(p1);

printf("%d\n",*p1);//100

printf("%d\n",a);//100

returen 0;

}

2)实现多个返回值

void caculator(int x, inty,int*add,int*jian,int*cheng,double*chu){

*add = x+y;

*jian =x-y;

*cheng = x*y;

*chu = x /(double)y;

}

int main(int argc,const char*argv[]){

int add;

int jian;

int cheng;

int chu;

caculator(3,4,&add,&jian,&cheng,&chu);

printf("add=%d,jian=%d,cheng=%d,chu=%d",add,jian,cheng,chu);

return 0;

}

8 二级指针

如果一个指针变量存放的是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量,也就是“二级指针”

定义一个二级指针 int **p =&p

int a =10;

int *p =&a; p的值时a的地址

int**p=&p; **p 就是取出 p里面存储的地址,而p存的是&a的地址,就是a的值

9 指针为什么要区分类别

不同类别表示职能存不同的类型的地址

int *p 便是指针职能存放int类型的地址

int a=5;

char *p=&a; a占四个字节,而这里每次只取一个字节。数据会改变

所以是什么类型的变量 就用什么类型的指针

二、指针与数组

1 数组指针;

指针变量可以指向数组的某个元素(把某一元素点地址放到相应的地址)

所谓数组元素的指针就是数组与元素的地址

指针数组的作用: 使用数组指针间接访问数组的元素

数组指针的定义:int *p 和定义变量指针一样

数组指针的初始化

int a[4]={1,2,3,4};

int *p=a //数组指针,定义了一个指针变量p赋值数组的首地址(第一个元素到地址),p指向数组的第一元素

int *p =&a[0]//等价上面一句话。

2.数组指针的用法

数组指针如何访问数组的元素:

p+1 表示指向数组的下一个元素

p-1表示指向数组的上一个元素

也可用*p++ 是个指针变量,是变量所以也可以++

int a[5]={1,2,3,4,5};

int*p =a;//表示p指向数组的第一个元素

*(p+1) = a[1];

使用数组指针和使用数组名的区别

用数组指针遍历数组

for(int i=0;i<4;i++){

printf("%d\t",*p++); //p指向数组的首元素

}

数组名a是一个常量不能++

总结:

引用一个数组元素,可以用两种方法

1下标法 如a[i]形式

2指针法如*(a+i)或*(p+i)

3a是常量(a++是错误的),p是变量(p++正确)

3.一维指针数组

一个数组的元素值为指针则是指针数组。白话存放指针的数组,就是指针数组

指针数组的一般形式 类型说明符*数组名[数组长度]

类型说明符为指针说指向的变量的类型

int *p[3]

表示p时一个指针数组,它有是三个元素,诶个元素都是一个指针,指向整型变量。

指针数组的使用 int p*[3]={&a,&b,&c};

p[0] =&a; a的地址 p数组的首地址

p就是指针数组的地址 访问a 的值 *(p[0])

4.指针变量之间的运算

两个指针之间的减法运算,

1》 0x0006 -0x003 =3(意义不大)

2》常见的用法: 两个指针指向同一个数组

判断两个指针变量指向的元素是否连续

判断两个指针变量之间相隔几个元素

int a[5]={2,3,4,5,6};

int *p=a;//p指向了数组的书元素

int *p1 =&a[3]; p1指向了数组的第四个元素

//地址值(p1-p)/sizeof(int)

printf("p1 - p =%d\n",p1-p);

如果两个指针变量指向同一个元素 那么他们相减等结果时0

判断两个指针变量指向的元素是不是相邻,如果相邻他们相减的结果 绝对值为1

两个指针之间的运算关系 p1 >p == 1 表示的是p1在高位值

p1 >p ==0 表示p在高位

注意:两个指针之间没有加法。

5用数组名访问二维数组

int a[3][4]={1,2,3,5,7},{9,11,13,15},{17,19,21,23};

a代表地0行点首地址 a+1表示第一行首地址 a+2表示第二行的首地址,所以a+i代表行号

a[0] 表示第0行第0列第一个的地址,a[0]+1表示第0行第1列第一个的地址 a[0][j]表示第0行第j列的第一个的地址

15 普通指针访问二维数组

int a[2][3]={1,2,3,4,5,6};

int *p =a;

for (int i =1; i< 6;i++){

printf("%d",*p++);

}

这里是应为数组他排列示在内存是这样的。

1

2

3

4

。。

说一可以写成*p++

6二维数组指针

行指针 ,用来表示指向二维数组的每一行,存放的是首地址

定义格式:数据类型 (*行指针变量名)[数组的第二维的长度];

二维数组指针的初始化

int a[2][3];

// a= &a[0] = a[0] == &a[0][0]

首行第一个元素的地址 ,首行地址 ,首行首列元素地址 都可以表示位二维数组的地址

int (*p)[3]=a;

二维指针的使用

*(*(a+i)+j)//就是获取二维数组的每一个元素

二维数组指针遍历数组
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a[2][3] = {{1,2,3,},{4,5,6}};
int (*p)[3] = a; //二维数组指指针  p可以代替数组名a来用
//数组的遍历
for (int i =0;i<2;i++){
for (int j=0; j<3; j++) {
printf("%d\t",*(*(p+i)+j) );//  *(*(a+i)+j)
}
return 0;
}


7 指针数组和二维数组指针的区别

两者都可以用来表示二维数组 但是便是方法和意义不同

int *p[3]={&a,&b,&d};p是一个指针数组

//表示配饰一个指针数组,有三个下标为p[0];p[1];p[2];均为指针变量

int *p[2]={a[0];a[1]};

int (*p)[3];//二维数组指针 表示一个指向二维数组的指针变量

四、 字符串指针

字符串指针指向 字符窜

char *变量名=" 字符串";//”字符串内容“是常量

char *str="wearefamily" 这个字符串是存储在常量去的

str只是保存了字符串常量的首地址。 指针变量都是占8个字节的

str是指针变量 ,str 还可以指向别的字符串常量 当指向"hahha"

这时str保存的是"hahha"

读取字符串的某个字符

prinf("%c\t",*(str+2))

for (inti =1;i<strlen(str;i++){

printf("%c\t" *(str+i) );

}

*(str+2)='x';错误。应为字符串常量是在常量存储区的,保存在常量区保存的数据都是只读 不能修改。

char*str2 ;

scanf("%s",str2);z这样不能写应为str2 没有赋初始值 ,为野指针

可以这样定义int *str2= NULL; //空的意思

str2=malloc(100);者句话作用是先给申请一个100自己度内存str2

char 型指针数组 和字符数组的区别

二维字符数组

char ch[3][4]+{{},{}<{}};

或者 char ch3[3][5]={"abc","cdf","sdsa"}

//可以存储多个字符串

//第一维存的事字符串的首地址

//每个字符串的长度,不能超过二维长度。

char 类型的指针数组

char *name[3]={"asdad","adadsadf","qwqewqeq"};

遍历

for (int i=1;i<3,i++){

printf("%s",name[i])

}

char ch[]="abc"; 这是存储在栈区

字符指针和字符数组

字符指针 char *ss ="abc";

ss 是一个指针变量 ,指向可以改变

ss = "helloword";

字符数组 char s1[3]= "abc";

s1是个常量,不能被赋值 。

应用字符串排序。

应用字符串排序。
#include <stdio.h>
#include <string.h>
void sortString(char*arry[],int length);

int main(int argc, const char * argv[]) {
//定义char类型的指针 来存储临时的地址

char *name[]={"CHINA","AMERICA","AUSTRALIA","FRANCE","GERMAN"};

sortString(name, 5);

return 0;
}
void sortString(char*array[],int length){
char *temp;
for(int j=0;j< length-1;j++){
for (int i=0;i< length-1-i;i++){
//比较两个字符串的ascii的大小

if (strcmp(array[i],array[i+1]) >0){
//实现array[i]和array[i+1]地址的交换
temp = array[i];
array[i]=array[i+1];
array[i+1]=temp;

}

}
}
for (int i =0; i<length; i++){
printf("%s\n",arry[i]);
}

}


五、指针与函数

1.指针函数

概念 指针函数就是一个函数返回的事一个指针(即地址)这中国返回指针值的函数就叫指针函数

2定义 类型说明符 *函数名(形参){

函数体

return 地址

}

在函数名前加了一个"*" 表示这是一个指针函数 ,即返回值是一个指针,类型说明符表示返回的指针指向的数据类型

int *max(int x,int y){

return x>y ? &x:&y;

}

int *max1(int *x,int *y){

return *x > *y? x : y;

}

int main(int argc,const char*arv[]){

int a =3,b=4;

printf("a =%p\n",&a);

printf("b = %P\n",&b);

int *p=max(a,b); 这里传进去后只是返回到形参的值。形参变量事新分配空间

int *p1=max1(&a,&b);这里才是实参的改变 ,变量没有新分配空间只是形参和实参的地址传递

}

应用 通过指针输入1到7 到数字 输出对应的星期名
#include <stdio.h>
char * getWeekday(int n);
int main(int argc, const char * argv[]) {
printf("%s\n",getWeekday(1));
return 0;
}

char * getWeekday(int n){
char * weekday[]={
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
"星期日",
};
return n<8&&n>0 ? weekday[n-1]: "输入错误!";

}


2 函数数的指针

在c语言中 ,函数名就是该函数所占内存区的首地址, 这个函数点首地址赋给一个指针变量,使该指针变量指向改函数。然后可以找到并调用这个函数,把这种指向函数的指针变量称为“函数指针变量”

函数指针变量:存放函数的首地址的指针变量就是函数指针变量

函数指针变量的定义 (*变量名)(函数的参数);

函数的声明 :

int sum(int a,int b);------->函数指针int (*p)(int a,int b);

这里定义了一个函数指针p1 ,p1可以存放返回值是int类型,并且有两个形参 还都是int类型的函数地址

p1 = sum ;//sum存的就是函数在内存中的首地址

int sum (int a,int b){

return a+b ;

}

int main(){

int a =4,b=5;

int (*p)(int,int);//定义函数指针 ,定义指针函数的时候可以不用写行参名

p =sum ;//初始化 sum 函数的首地址

}

3. 函数指针调用函数

#include <stdio.h>

int sum (int a,int b){

return a+b;

}

int main(int argc, const char * argv[]) {

指针函数的使用

//定义一个指针函数

int (*P)(int,int);

//给函数指针初始化

p=sum;

//用函数指针间接调用函数

int s= p(23,45);

printf("%d",s);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: