C语言指针详解

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 **pp为指针变量(二级指针)存放一级指针地址,一级指针指向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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值