指针填坑

指针

1.指针运算
*(p1 - 1) :p1指向的地址减一个存储单元,也就是后移4个字节的地址中存储的数据
*p1 - 1:p1指向的存储单元值减1

2.指针与函数
2.1指向函数的指针

int max(int x,int y){}
int main(void){
int (p)(int,int);
int a,b,c;
p = max;
scanf("%d %d",&a,&b);
c = (
p)(a,b);
return 0;
}

int (p)(int,int);//p是一个指向函数的整型指针
c = (
p)(a,b);//p指向函数,相当于调用了函数

2.2返回指针的函数
int *max(int *x,int *y);//max函数调用后返回值的数据类型是整型指针

3.void指针类型
void指针类型,可以用来指向一个抽象类型的数据,在将它的值赋给另一个指针变量时要进行强制类型转换,使之适合于被赋值的变量的类型.例:

char *p1;
void *p2;
p1 = (char *)p2;
p1 = (void *)p2; //可以使用(void *)p1将p1转换成void *类型

不只对变量可以使用void指针类型,也可以将一个函数定义为void *类型

void * fun(char ch1,char ch2);
p1=(char *)fun(ch1,ch2); //类型转换

4.简单链表

include <stdio.h>

include <stdlib.h>

struct list{
int data;
struct list *next;
};
typedef struct list node;
typedef node *link;

int main(){
link ptr,head; /创建指针对象/
int num,i;
ptr = (link)malloc(sizeof(node)); /分配空间/
head = ptr; /分配空间/
printf("plesase input 5 numbers==>\n"); /输入数据/
for(i=0;i<=4;i++){ /循环创建对象/
scanf("%d",&num);
ptr->data = num; /对象赋值/
ptr->next = (link)malloc(sizeof(node));/分配空间/
if(i == 4)
ptr->next = NULL; /最后一个指针指向空/
else
ptr = ptr->next; /指针指向下一个对象/
}
ptr = head;
while(ptr != NULL){
printf("The value is ==>%d\n",ptr->data);/对象不为空就输入值/
ptr = ptr->next;
}
return 0;
}

5.指针与数组

&grade[3] = &grade[0] + 3 * 4 //含义是grade[3]的地址等于grade[0]的地址加上12
可以写成以下通式
数组中下标为N元素的地址 = 数组的首地址 + N * sizeof(DataType)

使用数组名访问元素使用指针变量一样

5.1指针与多维数组

int array[1][2];
array + 1 //数组下标1 行首地址
&array[1] //数组下标1 行首地址

array[1] //等价array[1]+0,指array[1][0]元素的地址
array[1] + 2 //array[1][2]的地址
*(array+1)+2 //array[1][2]的地址

((array + 1) + 2) //array[1][2]的值
*(array[1] + 2) //array[1][2]的值

5.2指针与数组参数

6.指针与字符串

字符串的定义自动包含了指针,
例如定义message1[100],为100个字符声明存储空间,并自动创建一个包含指针的常量message1,存储的是message1[0]的地址。与一般的常量一样,指针常量指向是明确的,不能被修改。
字符串,可以不按声明一般数组的方式定义数组的维数和每一维的个数,可以使用新的方法,即用指针创建字符串。例:

char *message2 = "Talk is cheap";
char message1[20] = "Show me the code";

message1与message2不同,message1按照数组定义方式定义,message2用指针创建字符串,message1形式要求有固定的存储该数组的空间,而且,因为message1本身是数组名称,一旦初始化,再执行下面的语句就是错误的:

message1 = "hello !";

message2本身是一个指针变量。通过显式的方式明确了一个指针变量,对于message2执行了初始化后,再执行下面的代码是正确的:

message2 = "hello !";

从分配空间的角度分析,二者也不同。message1指定了一个存储10个字符位置的空间。message2不同,它只能存储一个地址,只能保存指定字符串的第一个字符的地址。

7.指针的指针
使用指针的指针访问字符串数组

int main(){
char seasons[]={"winter","spring","summer","fall"};
char **p;
int i;
for(i=0;i<4;i++){
p=seasons+i;
printf("%s\n",
p);
}
return 0;
}

seasons是指针数组,每个元素都是指针,seasons是字符串"winter"的指针,seasons+i等价与&seasons[i],也就是每个字符串首字符的地址。

8.指针数组和数组指针

指针数组是指数组由指针类型的元素组成。比如 int *p[10],数组p由10个指向整型元素的指针组成;比如p[0],是一个指针变量,使用跟一般指针用法一样,就是这些指针有同一个名字,需要使用下标来区分。

int main(){
int array[2][3] = {1,2,3,4,5,6};
int i,j;
int (*p)[3];
p = array;
for(i = 0;i < 2;i++){
for(j = 0;j < 3;j++)
printf("array[%d][%d] = %d\n",i,j,p[i][j]);
}
return 0;
}

/**
**报数游戏
**从第1个报数,报到3的退出,问最后留下来的是哪个
**/

int main(){
int i,k,m,n,num[nmax],p;
printf("输入总人数:");
scanf("%d",&n);
p = num;
for(i = 0;i < n;i++)
(p + i) = i + 1;//赋值
i = 0;k = 0;m = 0;//m:退出的人数 k:报的数 i:地址偏移
while(m < n - 1){
if(
(p + i) != 0)
k++;
if(k == 3){
(p + i) = 0;
k = 0;//报到3恢复0
m++;
}
i++;
if(i == n)
i = 0;//数组结束 重置到数组首地址
}
while(
p == 0)
p++;
printf("%d 号留下了\n",
p);
return 0;
}

posted on 2018-12-03 14:03  destiny_sea  阅读(119)  评论(0)    收藏  举报