欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Pointer_6

程序员文章站 2022-06-23 13:40:35
...

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

struct myStruct
{
    int a;
    int b;
    int c;
};

int func(char* str)
{
    // 统计字符串中各个字符的ASCII码值之和
    int num = 0;
    int len = strlen(str);
    for(int i = 0; i < len; i++)
    {
        num += *str;
        str++;
    }
    return num;
}


void func_1(char* s)
{
    char c;
    c = *(s + 3);
    *(s + 3) = *(s + 0);
    *(s + 0) = c;

    c = *(s + 1);
    *(s + 1) = *(s + 2);
    *(s + 2) = c;
}


int main()
{
    struct myStruct ss = {2, 3, 4};
    struct myStruct *ptrStruct = &ss;
    int *p = (int*)ptrStruct;

    // 通过ptrStruct访问ss的三个成员变量
    printf("%d\n", ptrStruct->a);
    printf("%d\n", ptrStruct->b);
    printf("%d\n", ptrStruct->c);
    printf("\n");

    // 通过p来访问ss的三个成员变量,这样访问变量是不正规的
    printf("%d\n", *p);
    printf("%d\n", *(p + 1));
    printf("%d\n", *(p + 2));

    // 所有的C/C++编译器在排列数组的单元时,总是把各个数组单元存
    // 放在连续的存储区里,单元和单元之间没有空隙。但在存放结构对象的
    // 各个成员时,在某种编译环境下,可能会需要字对齐或双字对齐或者是
    // 别的什么对齐,需要在相邻两个成员之间加若干个"填充字节",这就导
    // 致各个成员之间可能会有若干个字节的空隙。
    // 即使*p访问到了结构对象ss 的第一个成员变量a,也不能保证*(p+1)
    // 就一定能访问到结构成员b。因为成员a 和成员b 之间可能会有若干填充字节,
    // 说不定*(p+1)就正好访问到了这些填充字节呢。这也证明了指针的灵活性。
    // 要是你的目的就是想看看各个结构成员之间到底有没有填充字节,
    // 嘿,这倒是个不错的方法。不过指针访问结构成员的正确方法应该是使用指针ptr

    char sz[20] = "test";
    printf("%d\n", func(sz));
    printf("\n");

    int n1 = 125;
    printf("%d\n", n1);
    func_1((char*)&n1);
    printf("%d\n", n1);
    printf("\n");

    // 注意这是一个32 位程序,故int 类型占了四个字节,char 类型占一个字节。
    // 函数func_1的作用是把一个整数的四个字节的顺序来个颠倒。注意到了吗?
    // 在函数调用语句中,实参&n1的结果是一个指针,它的类型是int *,
    // 它指向的类型是int。形参这个指针的类型是char *,它指向的类型是char。
    // 这样,在实参和形参的结合过程中,我们必须进行一次从int *类型到
    // char *类型的转换。
    // 我们可以这样来想象编译器进行转换的过程:编译器先构造一个临时指针char *temp,
    // 然后执行temp=(char *)&n1,最后再把temp 的值传递给s。所以最后的结果是:
    // s的类型是char *,它指向的类型是char,它指向的地址就是n1的首地址。


    unsigned int n2 = 20345686;
    unsigned int *pn2 = (unsigned int *)n2;     // 将一个无符号整数值转换为一个指针
    // 间接引用n2时,会出现内存访问错误,但可以将地址输出
    //printf("%d\n", *pn2);     
    printf("0x%p\n", pn2);
    printf("\n");

    pn2 = &n2;
    // 将一个无符号指针转换为无符号整数
    unsigned int n3 = (unsigned int)pn2;
    printf("%d\n", n3);
    printf("0x%p\n", n3);

    // getchar()是一个缓冲函数,结束时,必须输入一个回车,getchar()函数才从
    // 键盘缓冲区中读取字符
    getchar();
    return 0;
}
相关标签: pointer

推荐阅读