C语言基础学习——第5天(指针)

来源:互联网 发布:淘宝画手兼职 编辑:程序博客网 时间:2024/05/17 21:35

00basic_concept.c

#include <stdio.h>int main(void){    int a = 16;    // 指针类型是复合类型, 必须从某个基础类型派生.    // p 是一个变量/对象. p 是 int * 类型.    // p 指向 int 类型.    // 这里的 * 是类型说明符.    int *p;    // p 指向 a.    p = &a;    printf("p's addr: %p, p's val: %p\n", &p, p);    printf("a's addr: %p, a's val: %d\n", &a, a);    printf("------------------\n");    // 这里的 * 是运算符, 解引用运算符, 间接访问运算符.    printf("*p   = %d\n", *p);    *p = 32;    printf("a    = %d\n", a);    printf("------------------\n");    // p[i] = *(p + i)    printf("p[0] = %d\n", p[0]);    p[0] = 25;    printf("a    = %d\n", a);    return 0;}运行结果:p's addr: 0xbfa2612c, p's val: 0xbfa26128a's addr: 0xbfa26128, a's val: 16------------------*p   = 16a    = 32------------------p[0] = 32a    = 25

01basic_concept.c

#include <stdio.h>int main(void){    // 没有初始化的指针 野指针 dangling pointer    int *p;    printf("p = %p\n", p);    // 向一个随机地址赋值, segment fault.    // *p = 123;    // printf("*p = %d\n", *p);    // 就算指定地址    p = (int *)0x12345;    printf("p = %p\n", p);    // 向指定地址赋值, segment fualt.    // 因为不知道指定地址是否合法.    *p = 456;    printf("*p = %d\n", *p);    return 0;}运行结果:p = 0xb77c0ff4p = 0x12345Segmentation fault (core dumped)

02basic_concept.c

#include <stdio.h>// 类型系统和表达式系统// 类型 决定 类型之上 的操作是否合法.int main(void){    unsigned long p = 0;    int a = 16;    p = (unsigned long)&a;    printf("a = %d, *p = %d\n", a,*(int *)p);    return 0;}运行结果:a = 16, *p = 16

03void_pointer.c

#include <stdio.h>int main(void){    int *p = NULL;    void *vp = NULL;    int a = 16;    // p  --> a    p = &a;    // pv --> a    // void * 和任意指针类型兼容.    vp = p;    printf("&a = %p, p = %p, vp = %p\n", &a, p, vp);    printf("a = %d, *p  = %d\n", a, *p);    // 不能对 void * 类型指针变量解引用, 要强转之后再来解引用.    printf("a = %d, *vp = %d\n", a, *(int *)vp);    return 0;}运行结果:&a = 0xbfda03a4, p = 0xbfda03a4, vp = 0xbfda03a4a = 16, *p  = 16a = 16, *vp = 16

04pointer_access.c

#include <stdio.h>int main(void){    int *p = NULL;    int a = 16;    int b = 12;    printf("&a = %p, &b = %p\n", &a, &b);    p = &a;    printf("*p = %d\n", *p);    printf("------------------\n");    printf("&a = %p, p = %p\n", &a, p);    // p + 1 地址实际加多少字节, 和指针类型相关. 在此是加4, 如果是char *类型则加1    p++;    printf("after p++.\n");    printf("&b = %p, p = %p\n", &b, p);    printf("------------------\n");    printf("*p = %d\n", *p);    return 0;}运行结果:&a = 0xbffc40e4, &b = 0xbffc40e8*p = 16------------------&a = 0xbffc40e4, p = 0xbffc40e4after p++.&b = 0xbffc40e8, p = 0xbffc40e8------------------*p = 12

05pointer_access.c

#include <stdio.h>int main(void){    int a = 0x44332211;    int *p = NULL;    char *pc = NULL;    p = &a;    printf("a = %#x, *p = %#x\n", a, *p);    pc = (char *)p;    // 解引用指针, 取多少内容, 和指针类型相关.    printf("*pc        = %#x\n", *pc);    printf("*(pc + 1)  = %#x\n", *(pc + 1));    printf("*(pc + 2)  = %#x\n", *(pc + 2));    printf("*(pc + 3)  = %#x\n", *(pc + 3));    return 0;}运行结果:a = 0x44332211, *p = 0x44332211*pc        = 0x11*(pc + 1)  = 0x22*(pc + 2)  = 0x33*(pc + 3)  = 0x44pc是低地址, 存放的是尾端0x11,pc+3是高地址, 存放的是首端0x44,由此可见, 本计算机属于"小端"字节序

06pointer_operation.c

#include <stdio.h>void rand_a(int *p, int len){    int i;    for (i = 0; i < len; i++)        *(p + i) = rand() % 100;}void print_a(int *p, int len){    int i;    for (i = 0; i < len; i++)        printf("%d ", *(p + i));    putchar('\n');}int max(int *p, int len){    int i;    int m = *p;    for (i = 0; i < len; i++)    {        if (*(p + i) > m)            m = *(p + i);    }    return m;}int min(int *p, int len){    int i;    int m = *p;    for (i = 0; i < len; i++)    {        if (*(p + i) < m)            m = *(p + i);    }    return m;}void reverse(int *p, int len){    int i;    for (i = 0; i < len / 2; i++)    {        *(p + i) ^= *(p + len - i - 1);        *(p + len - i - 1) ^= *(p + i);        *(p + i) ^= *(p + len - i - 1);    }}void bubble_sort(int *p, int len){    int i, j;    for (i = 0; i < len - 1; i++)    {        for (j = 0; j < len - i - 1; j++)        {            if (*(p + j) > *(p + j + 1))            {                *(p + j) ^= *(p + j + 1);                *(p + j + 1) ^= *(p + j);                *(p + j) ^= *(p + j + 1);            }        }    }}int main(void){    int a[10];    rand_a(a, 10);    print_a(a, 10);    printf("--------------------\n");    printf("max = %d\n", max(a, 10));    printf("min = %d\n", min(a, 10));    printf("--------------------\n");    printf("reverse:\n");    reverse(a, 10);    print_a(a, 10);    printf("--------------------\n");    printf("sort:\n");    bubble_sort(a, 10);    print_a(a, 10);    return 0;}运行结果:83 86 77 15 93 35 86 92 49 21--------------------max = 93min = 15--------------------reverse:21 49 92 86 35 93 15 77 86 83--------------------sort:15 21 35 49 77 83 86 86 92 93

07char_pointer.c

#include <stdio.h>int main(void){    // china unix 会存放入数组中(可读可写).    // 数组 s 在main函数的运行栈中.    char s[] = "china unix";    printf("s = %s\n", s);    s[0] = 'C';    s[6] = 'U';    printf("s = %s\n", s);    printf("------------------------\n");    // 下面这个 china unix 存放在只读数据段(.rodata)    // 将 china unix 的字符串首地址给了 str    char *str = "china unix";    printf("str = %s\n", str);    // 试图修改只读段中的内容, 将导致 段错误/segment fault.    *(str + 6) = 'U'; // str[6] = 'U';    return 0;}运行结果:s = china unixs = China Unix------------------------str = china unixSegmentation fault (core dumped)

08char_pointer.c

#include <stdio.h>int main(void){    char s[] = "12345ABCDE";    char *str = "12345ABCDE";    printf("s[6]        = %c\n", s[6]);    printf("*(s + 6)    = %c\n", *(s + 6));    printf("------------\n");    printf("str[6]      = %c\n", str[6]);    printf("*(str + 6)  = %c\n", *(str + 6));    printf("==================\n");    // "12345ABCDE" 这个字符串就是一个首地址    printf("12345ABCDE[6]      = %c\n", "12345ABCDE"[6]);    printf("*(12345ABCDE + 6)  = %c\n", *("12345ABCDE" + 6));    return 0;}运行结果:s[6]        = B*(s + 6)    = B------------str[6]      = B*(str + 6)  = B==================12345ABCDE[6]      = B*(12345ABCDE + 6)  = B
0 0
原创粉丝点击