by:jkloli
1. 指针常见形式详解(重要)
32bit架构内存地址长度4字节,32bit程序中指针大小4字节。
64bit架构内存地址长度8字节,64bit程序中指针大小8字节。
int* a,b; 等价于 int *a;int b;而不等价于 int *a; int *b;
//定义指针变量,用来存放整型变量i的地址
int *i_pointer
//间接存放i的值,可以先找到存放i的地址的变量i_pointer,从中取出i的地址(2000),然后取出i的值3
int i=2000;
int *pointer;//1.这里*不是取值操作符,而是声明指针的特征(表示这是个指针变量,变量名为pointer)
i_pointer=&i;//2.&取i的地址赋给i_pointer
printf("%d\n",*pointer);//3.这个是取值操作符,进行指针解引用
void main()
{
int *a,*b,c;
c=5;
a=&c;//指针a所在地址单元存放c的地址
b=a;
printf("%d ",b);//指针b所在地址单元存放c的地址
}
/*&c *a *b
1703720 内容 1703720 1703720
地址 1703728 1703724
*/
辨认准则:找到变量名(没有就看最内部结构),先向右看(不跳过括号),然后向左看(不跳过括号),然后跳出一层括号,重复上述操作。
比如:int* a[5]; 首先向右看,它是一个5元素数组,然后向左看指向int类型,所以a是个有5个指向int类型指针的数组。
含义 | |
---|---|
int a[n] | int数组 |
int *p[n] | 指针数组p,由n个指向整型的指针元素构成 |
int (*p)[n] | p为指向含n个元素的一维数组的指针变量 |
int f() | f为带回一个整型函数值的函数 |
int *p() | p为带回一个指针的函数,该指针指向整形数据 |
int (*p)() | p为指向函数的指针,该函数返回整型值 |
int **p | p为指针变量(二级指针)存放一级指针地址,一级指针指向int变量 |
int (*(*v)[])() | v是一个指针,指向一个数组,数组元素是指针,每个指针指向一个int函数。 |
typedef void (*func_ptr)(char *); | 定义了一个新的类型名func_ptr,这个类型是一个指向函数的指针,参数char *类型,返回值void类型 |
*&a等价于变量a
&*a等价于&a
char b[4][6]本质为char*s[4],s是一个含4元素数组,数组元素为char*。
#include<stdio.h>
#include<string.h>
#include <malloc.h>
void main()
{
char *str=NULL;
int s=30;
str=fa(s);
printf("str=%s\n",str);//printf(%s)需要的是一个地址,然后从这个地址开始打印字符串遇到空格或\0停止
free(str);//防止内存泄漏。free()只能释放指针所指向的那片内存。
str=NULL;//防止产生野指针
system(pause);
}
char* fa(int x)//指针数组带回一个指针
{
char *pstr=NULL;
x++;
pstr=fb(10);
return pstr;//指针变量pstr到这里结束
}
char* fb(int m)
{
char *pa="123456";//pa指针在栈区
//123456在堆区
char *p=NULL;
//指针变量在栈区分配4字节
{int i=30;}
p=(char *)malloc(100);
//malloc函数开辟一块堆区存储空间,
strcpy(p,"wudunxiong 123456");
//wudongxiong 123456在常量区
return p;//返回给主调函数fa()
}
2. 野指针
野指针是指程序员或操作者不能控制的指针。野指针不是NULL指针,而是指向“垃圾”的指针。
造成“野指针”的原因主要有:
1.指针变量没有初始化,任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指。在初始化的时候要么指向合法的指针,要么指向NULL。
2.指针变量被free或delete之后,没有设置为NULL。它们只是把指针所指的内存给释放掉,但指针本身还有值。
3.指针操作超越了变量的作用范围。 注意其生命周期。
3. 编写swap的注意
int main()
{ int a=10, b=20;
printf("a=%d,b=%d\n", a, b);
swap(&a, &b);
printf("a=%d,b=%d\n", a, b);
return 0;
}
void swap(int p, int q)
{ int t;
t=p; p=q; q=t;
}
上面代码是错的,p,q不指向a,b,没法改值。
修改后的swap函数可以是:
void swap( int *p, int *q )
{int t;
t=*p; *p=*q; *q=t;
}
4. 指针的使用
//错误示范
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include <stdio.h>
typedef struct node {
int data;
struct node* next;
}node;
void create(node *h){
h = (node*)malloc(sizeof(node));
//此时h!=NULL,head==NULL
h->data = 10;
}
int main() {
int i, j;
node* head=NULL;
create(head);//值传递,h=head=NULL
printf("%d", head->data);
//报错,因为一级指针并没影响到head指针
return 0;
}
//更正方法1: 返回一级指针
node* create(node *h){
h = (node*)malloc(sizeof(node));
h->data = 10;
return h;
}
head=create(head);
//更正方法2: 用二级指针指向一级指针实现引用传递
void create(node **h){
*h = (node*)malloc(sizeof(node));
(*h)->data = 10;
}
create(&head);
5. 指针偏移
char a[10] = "hello world";
char* p = a;
p+1偏移一个字节(sizeof(char))。
char b[4][10] = { 0 };
char (*p)[10] = b;
p + 1偏移10个字节。
Q群:709342059