C语言----------指针

地址

注: 把指针比喻成门牌号,信封邮寄地址,现在我看到指针就想起门牌号,信封地址

#include "stdio.h"

int main()
{
    int a = 10;
    int *p = &a;
    printf("%p
", p);
    return 0;  
}

// output
0x7fff5fbff81c

 分析:是系统 RAM 中的特定位置,通常以十六进制的数字表示,系统通过这个地址,就可以找到相应的内容,当使用80386时,我们必须区分以下三种不同的地址:逻辑地址,线性地址,物理地址;在进行C语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址(偏移地址),不和绝对物理地址相干,比如上面那个"0x7fff8b6a378c" 就是逻辑地址。逻辑地址不是被直接送到内存总线,而是被送到内存管理单元(MMU)。MMU由一个或一组芯片组成,其功能是把逻辑地址映射为物理地址,即进行地址转换。下面是转换关系图:

 指针

一、指针变量的定义

指针:一个变量的指针就是该变量的地址(地址就是指针)

指针变量:存放变量地址的变量,他是用来指向另一个变量

1. 格式:变量类型 *指针变量名;

2. 举例:int *p;   char *p2;

3. 注意:定义变量时的*仅仅是指针变量的象征

二、利用指针变量简单修改其他变量的值

1.指向某个变量

int a;

int *p;

p = &a;

或者

int *p = &a;

2.修改所指向变量的值

*p = 10;

3.在函数内部修改外面变量的值

int a = 10;
change(&a);

void change(int *n)
{
    *n = 20;
}

 4.指针使用注意:

int main()
{

/* 不建议的写法, int *p只能指向int类型的数据 int *p; double d = 10.0; p = &d;*/ /* 指针变量只能存储地址 int *p; p = 200; */ /* 指针变量未经过初始化,不要拿来间接访问其他存储空间 int *p; printf("%d ", *p); */ int a = 10; /* int a; a = 10; */ /* int *p; p = &a; */ // 定义变量时的*仅仅是一个象征,没有其他特殊含义 int *p = &a; // 不正确的写法 // *p = &a; p = &a; // 这个时候的*的作用:访问指向变量p指向的存储空间 *p = 20; char c = 'A'; char *cp = &c; *cp = 'D'; printf("%c ", c);
return 0;
}
// output
D

 练习小结:

#include <stdio.h>
void swap(int *v1, int *v2);

int main()
{
    /*
    int a = 10;
    int b = 11;
    
    swap(&a, &b);
    */
    
    
    int a2 = 90;
    int b2 = 89;
    
    swap(&a2, &b2);
    
    printf("a2=%d, b2=%d
", a2, b2);
    return 0;
}

/* 不能交换外面实参的值,仅仅是交换了内部指针的指向
void swap(int *v1, int *v2)
{
    int *temp;
    temp = v1;
    v1 = v2;
    v2 = temp;
}*/

// 完成两个整型变量值的互换
void swap(int *v1, int *v2)
{
    int temp = *v1;
    *v1 = *v2;
    *v2 = temp;
}

/* 交换的只是内部v1、v2的值
void swap(int v1, int v2)
{
    int temp = v1;
    v1 = v2;
    v2 = temp;
}*/

 指针疑问:/*

 %d int
 %f floatdouble
 %ld long
 %lld long long
 %c char
 %s 字符串
 %zd  unsigned long
 */

#include <stdio.h>

/*
 0000 0001
 0000 0010
 0000 0000
 0000 0000
 
 0000 0000 0000 0000 0000 0010 0000 0001
 */

int main()
{
    // 0000 0000 0000 0000 0000 0000 0000 0010
    int i = 2;
    // 0000 0001
    char c = 1;
    
    char *p;
    p = &c;
    
    //*p = 10;
    
    printf("c的值是%d
", *p);
    
    return 0;
}

void test()
{
    char c; // 1
    int a; // 4
    long b; // 8
    
    // 任何指针都占用8个字节的存储空间
    char *cp;
    int *ap;
    long *bp;
    
    printf("cp=%zd, ap=%zd, bp=%zd
",
           sizeof(cp),
           sizeof(ap),
           sizeof(bp));
}

三、指针与数组

1.将数组当做函数参数传入时,会自动转为指针

/*
 1.数组元素的访问方式
 int ages[5];
 int *p;
 p = ages;
 1> 数组名[下标]  ages[i]
 2> 指针变量名[下标] p[i]
 3> *(p + i)
 
 2.指针变量+1,地址值究竟加多少,取决于指针的类型
  int *   4
  char *  1
  double * 8
 */
void change(int array[]);

int main()
{
    // 20个字节
    int ages[5] = {10, 11, 19, 78, 67};
    
    change(ages);
    
    return 0;
}

// 利用一个指针来接收一个数组,指针变量array指向了数组的首元素
void change(int *array)
{
    printf("%d
", array[2]);
    //printf("%d
", *(array+2));
}

/*
void change(int array[])
{
    int s = sizeof(array);
    
    printf("%d
", s);
}*/

void test()
{
    double d = 10.8;
    double *dp;
    dp = &d;
    
    printf("dp = %p
", dp);
    printf("dp + 1 = %p
", dp + 1);
    
    int ages[5] = {10, 9, 8, 67, 56};
    
    int *p;
    // 指针变量p指向了数组的首元素
    p = &ages[0];
    // 数组名就是数组的地址,也是数组首元素的地址
    //p = ages;
    
    /*
     p ---> &ages[0]
     p + 1 ---> &ages[1]
     p + 2 ---> &ages[2]
     p + i ---> &ages[i]
     */
    
    //printf("%d
",  *(p+2));
    
    printf("%d
",  p[2]);
    
    /*
     for (int i = 0; i<5; i++) {
     printf("ages[%d] = %d
", i, *(p+i));
     }*/
    
    
    //    printf("%p
", p);
    //    printf("%p
", p + 1);
    //    printf("%p
", p + 2);
}

四. 指针与字符串

1.常量区

 存放一些常量字符串

 2.堆

 对象

 3.栈

 存放局部变量

掌握:

 定义字符串的2种方式

 1> 利用数组

 char name[] = "itcast";

  * 特点:字符串里面的字符是可以修改的

  * 使用场合:字符串的内容需要经常修改

 2> 利用指针

  char *name = "itcast";

  * 特点:字符串其实是一个常量字符串,里面的字符是不能修改

  * 使用场合:字符串的内容不需要修改,而且这个字符串经常使用

int main()
{
    char name[20];
    
    printf("请输入姓名:
");
    
    scanf("%s", name);
    
    // 'j' 'a' 'c' 'k' ''
    
    //printf("%c
", name[3]);
    
    //printf("刚才输入的字符串是:%s
", name);
    
    return 0;
}

// 定义字符串数组
void test2()
{
    char *name = "jack";
    
    //int ages[5];
    
    // 指针数组(字符串数组)
    char *names[5] = {"jack", "rose", "jake"};
    
    // 二维字符数组(字符串数组)
    char names2[2][10] = {"jack", "rose"};
}

// 定义字符串
void test()
{
    // 字符串变量
    char name[] = "it";
    name[0] = 'T';
    
    //printf("%s
", name);
    
    
    // "it" == 'i' + 't' + ''
    // 指针变量name2指向了字符串的首字符
    
    // 字符串常量
    char *name2 = "it";
    
    char *name3 = "it";
    
    //*name2 = 'T';
    
    //printf("%c
", *name2);
    
    printf("%p
%p
", name2, name3);
    
    //printf("%s
", name2);
}
原文地址:https://www.cnblogs.com/dj123456/p/4762607.html