• 深入理解c语言指针与内存


    一、将int强制转换为int指针,将int指针强转换为int

    void f(void)
    {
        int *p = (int*)100; //将int强制转换为int指针
        printf("%d\n",(int)p+1); //将int指针强转换为int, 然后+1
        printf("%d\n",(int)(p+1)); //将int指针加1(地址增加了4),强制转换为int
    }
    
    int main(int ac, char **av)
    {
        f();
        return 0;
    }
    

    运行结果:

    101
    104
    

    二、int指针转换为char指针

    #include <stdio.h>
    
    int main() {
        int a = 8;
        int* b = &a;
        int *c = (int*)((char*)b + 1);
        printf("b = %p, c = %p\n", b, c);
        *c  = 8;
        printf("%d\n", a);
        printf("b = %p, c = %p\n", b, c);
        printf("%d\n", *c);
        return 0;
    }
    
     
    

    运行结果:

    b = 0061FEC4, c = 0061FEC5
    2056
    b = 0061FEC4, c = 0061FE00
    1988445728
    
    

    运行完第7行:整数a的地址为b = 0x61fec4,内存值为08000000;指针c指向0x61fec5,是a的第二个字节的地址。(小端存储)

    运行完第8行,对c指向的内存赋值,这个四个字节被写为 08000000,因此a指向的内存被写为:00000808(b) = 2056(d)。

    但由于存储c这个指针的内存正好因此被破坏了,被修改为0061FE00,因此此次输出*c的内容是未知的。

    三、数组&指针

    1. S6.828

    #include <stdio.h>
    #include <stdlib.h>
    
    void f(void)
    {
        int a[4];
        int *b = malloc(16);
        int *c;
        int i;
    
    
        printf("1: a = %p, b = %p, c = %p\n", a, b, c);
    
        c = a;
        for (i = 0; i < 4; i++)
            a[i] = 100 + i;
        c[0] = 200;
        printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
               a[0], a[1], a[2], a[3]);
    
        c[1] = 300;
        *(c + 2) = 301;
        3[c] = 302;
        printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
               a[0], a[1], a[2], a[3]);
    
        c = c + 1;
        *c = 400;
        printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
               a[0], a[1], a[2], a[3]);
    
        c = (int *) ((char *) c + 1);
        *c = 500;
        printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
               a[0], a[1], a[2], a[3]);
    
        b = (int *) a + 1;
        c = (int *) ((char *) a + 1);
        printf("6: a = %p, b = %p, c = %p\n", a, b, c);
    }
    
    int main(int ac, char **av)
    {
        f();
        return 0;
    }
    
    

    运行结果:

    1: a = 0061FEA0, b = 007515B8, c = 0000003D
    2: a[0] = 200, a[1] = 101, a[2] = 102, a[3] = 103
    3: a[0] = 200, a[1] = 300, a[2] = 301, a[3] = 302
    4: a[0] = 200, a[1] = 400, a[2] = 301, a[3] = 302
    5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302
    6: a = 0061FEA0, b = 0061FEA4, c = 0061FEA1
    
    Process finished with exit code 0
    
    

    2. 在 C/C++中,数组和指针是相互关联又有区别的两个概念。

    • 当我们声明一个数组时,其数组的名字也是一个指针,该指针指向数组的第一个元素。我们可以用一个指针来访问数组。data1是一个数组,sizeof(data1)是求数组的大小。

    • data2声明为指针,尽管它指向了数组data1的第一个数字,但它的本质仍然是一个指针。

    • 在C/C++中,当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针。

    #include <stdio.h>
    #include <stdlib.h>
    
    int GetSize(int data[]){
    	return sizeof(data);
    }
    
    int main(void) {
    
    	int data1[] = {1,2,3,4,5};
    	int size1 = sizeof(data1);
    	int* data2 = data1;
    	int size2 = sizeof(data2);
    	int size3 = GetSize(data1);
    	printf("%d %d %d %d\n", size1, size2, size3);
    	return 0;
    }
    

    输出:

    64位操作系统

    20 8 8 8
    

    四、函数返回局部指针?

    1. 以下代码IDE会告警:Address of stack memory associated with local variable 't' returned。由于局部变量的指针分配在栈上,且函数执行完,栈内存会自动释放,因此reverseLeftWords的返回值总是为NULL,不能得到正确的结果。
    char* reverseLeftWords(char* s, int n){
        size_t sSize = strlen(s);
        if( n == 0 || n >= sSize) return s;
        char t[sSize+1];
        size_t i;
        for(i = 0; i < sSize; i++){
            t[i] = s[(i + n)% sSize];
        }
        t[i] = '\0';
        return t;
    }
    
    1. 需要通过malloc来分配堆上内存,返回堆内存地址。
    char* reverseLeftWords(char* s, int n){
        size_t sSize = strlen(s);
        if( n == 0 || n >= sSize) return s;
        char* t = (char*)malloc(sizeof(char*)*(sSize+1));
    
        size_t i;
        for(i = 0; i < sSize; i++){
            t[i] = s[(i + n)% sSize];
        }
        t[i] = '\0';
        return t;
    }
    
  • 相关阅读:
    socket 编程练习--UDP聊天程序
    练习 多线程
    练习二:求最大公约数
    练习一:单链表的反转,串的模式匹配
    【算法1】string 的全排列
    lw资料
    SDmenu滑动菜单获取导航连接部分代码
    FileOperate(个人资料)
    C/C++基本数据类型
    C++/MFC计算程序运行时间
  • 原文地址:https://www.cnblogs.com/qiangz/p/15769339.html
Copyright © 2020-2023  润新知