C语言指针

指针

1. 指针

尝试

指针类型占4字节

#include <stdio.h>

//类型* 标识符
//

int main() {
    int a=10, b=20, c=30;
    int *p1 = &a, *p2=&b, *p3=&c;

    printf("%d\n", p1); //10
    return 0;
}

示例

#include <stdio.h>

void func(int *x, int *y){
    *x = 3;
    *y = 5;
}

int main() {
    int a=10, b=20;
    func(&a, &b);
    printf("%d,%d", a,b); //3,5
    return 0;
}

数组连续存储

#include <stdio.h>

int main() {
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    int *p = NULL;

    for(int i=0; i<10; i++){
        printf("%p\n", &arr[i]);
    }
//    00000047ba1ff790
//    00000047ba1ff794
//    00000047ba1ff798
//    00000047ba1ff79c
//    00000047ba1ff7a0
//    00000047ba1ff7a4
//    00000047ba1ff7a8
//    00000047ba1ff7ac
//    00000047ba1ff7b0
//    00000047ba1ff7b4
    return 0;
}

指针偏移

#include <stdio.h>

int main() {
    int arr[10] = {10,20,30,40,50,60,70,80,90,100};
    int *p = NULL;

    // 首地址
    p = arr;
    p += 9;
    printf("%d\n", *p); //100
    return 0;
}

示例

#include <stdio.h>
#include <string.h>

int main() {

    char *p1 = "hdkhh";
    printf("%d\n", sizeof(p1));  //8
    printf("%d\n", strlen(p1));  //5

    p1 += 2;
    printf("%c\n", *p1);  //k

    return 0;
}

示例

#include <stdio.h>

int main() {

    int arr[10] = {10,20,30,40,50,60,70,80,90,100};
    double *p = NULL;
    int *p1 = NULL;
    char *p2 = NULL;

    printf("%d\n", sizeof(p)); //8
    printf("%d\n", sizeof(p1)); //8
    printf("%d\n", sizeof(p2)); //8

    p = (double*)&arr;
    p++;

    p1 = &arr[0];
    p1++;

    p2 = (char *)&arr[0];
    p2+=4;

    printf("%d\n", *((int*)p));  //30
    printf("%d\n", *p1);  //20
    printf("%d\n", *((int*)p2));  //20
    return 0;
}

2. 指针,函数

指针函数:是一个函数,但是函数的返回值类型是一个指针

函数指针:是一个指针,指针的指向是一个函数

指针函数

#include <stdio.h>

//指针函数
int * fun(){
    int a = 10;
    return &a;
};

void fun1 (int a, int b){
    printf("%d\n", a+b); //null
}

int add (int a, int b){
    return a+b; //null
}

//函数指针
void (*pFun)(int a, int b);

void fun3(int (*pF)(int, int), int a, int b){  //int (*pF)(int,int) = add
    printf("%d\n", pF(a, b));
}

int main() {

//    int *p = fun();
//    printf("%d\n", *p); //null

    pFun = fun1;
    pFun(1,2);

    fun3(add, 10, 10);

    return 0;
}

常量指针

指针常量

#include <stdio.h>

//不用初始化,能改变指向,指向的内容不能被修改
// const int *p;
//必须初始化,不能改变指向,可以改变指向的内容
// int* const p1 = NULL;

int main() {

    int a = 10;
    int b = 20;
    int* const p1 = &a;
    //p1 = &b; //不行
    *p1 = 100; // 可以改变内容
    
    return 0;
}

3. 指针,数组

指针数组:是一个数组,存储的是指针

数组指针:是一个指针,指向的是一个数组(二维数组起)

#include <stdio.h>

void fun(int(*arr)[3]){
    for(int i=0; i<3; i++){
        for(int j=0; j<3; j++){
            printf("%d\n", arr[i][j]);
        }
    }
}

int main() {

    int arr[3][3] = {
            {1,2,3},
            {4,5,6},
            {7,8,9}
    };
    
    //数组指针
    int (*p)[3] = arr;
    
    int a=1,b=2,c=3;
    int *p1=&a, *p2=&b, *p3=&c;
    
    //指针数组
    int *pa[3] = {p1,p2,p3};
    
    fun(arr);

    return 0;
}

多级指针

#include <stdio.h>

int main() {

    int arr[3][3] = {
            {1,2,3},
            {4,5,6},
            {7,8,9}
    };

    int *pa[3] = {arr[0],arr[1],arr[2]};
    int **pp = pa;
    printf("%d\n", *(*(pp+1)+2));  //6
    printf("%d\n", *((pp[2])-3));  //4
    printf("%p\n", *pp++);  //0000001f9efffcb0
    printf("%p\n", *pp);  //00000082181ff5dc
    printf("%d\n", **pp);  //4
    printf("%d\n", **pp++);  //4
    printf("%d\n", **pp);  //7

    //多级指针
    int num;
    int *a = &num;
    int **a1 = &a;
    int ***a2 = &a1;

    return 0;
}

char指针

#include <stdio.h>

int main() {
    
    char *str[4] = {
            "pro",
            "pro2",
            "haha",
            "hhhh"
    };

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

    return 0;
}

4. 结构体指针

#include <stdio.h>

typedef struct nodeDate{
    int a;
    char name[20];
}node;

int main() {

    node n; //struct nodeDate nd;
    n.a=10;
    printf("%d\n", n.a); //10

    //结构体访问成员用->
    node* p = &n;
    p->a=20;
    printf("%d\n", n.a); //20

    return 0;
}

示例

#include <stdio.h>

typedef struct nodeDate{
    int a;
    char name[20];
}node;

int main() {

    node n[5] = {
            {1, "aaa"},
            {2, "bbb"},
            {3, "ccc"},
            {4, "ddd"},
            {5, "eee"}
    };
    node *p = n;
    printf("%d %s\n", p[0].a, p[0].name);

    node *p1[5] = {&n[0], &n[1]};
    printf("%d %s\n", p1[0]->a, p1[0]->name);

    return 0;
}

偏移

#include <stdio.h>

typedef struct nodeDate{
    int a;
    char name[20];
}node;

int main() {

    node n[5] = {
            {1, "aaa"},
            {2, "bbb"},
            {3, "ccc"},
            {4, "ddd"},
            {5, "eee"}
    };
    node *p = n;
    printf("%d\n", p->a); //1
    printf("%d\n", (p+2)->a); //3
    printf("%d\n", (*(p+2)).a); //3
    
    return 0;
}

动态内存分配

通过 malloc, calloc, realloc

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {

    //赋值条件,类型相同
    int *p = (int *) malloc(100);
    *p =10;
    *(p+1) = 20;
    printf("%d %d\n", *p, *(p+1)); //10 20
    //释放内存
    free(p);

    int *p1 = (int *) malloc(sizeof(int)*25);
    for(int i=0; i<25; i++){
        *(p1+i) = i+1;
    }
    for(int i=0; i<25; i++){
        printf("%d\n", p1[i]); //*(p+i)
    }
    free(p1);
    printf("1----------------------------------------------------------------\n");

    // 赋值0
    memset(p1,0,sizeof(int)*25);
    for(int i=0; i<25; i++){
        printf("%d\n", p1[i]); //*(p+i)
    }
    free(p1);
    printf("2----------------------------------------------------------------\n");

    int *p2 = (int *) realloc(p2, sizeof(int)*25);  //重分配内存,不会初始化
    p2 = (int *) realloc(p2, sizeof(int)*50);
    for(int i=0; i<25; i++){
        *(p2+i) = i+1;
    }
    for(int i=0; i<25; i++){
        printf("%d\n", p2[i]);
    }
    free(p2);
    printf("3----------------------------------------------------------------\n");

    int *p3 = (int *) calloc(25, sizeof(int));  //默认初始化为0
    for(int i=0; i<25; i++){
        printf("%d\n", p3[i]);
    }

    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容