1、指针(理解、使用)

1.指针/指针变量的定义
  地址
    内存单元的编号
    从零开始的非负整数
    范围:4G【0~4G-1】
  指针/指针变量

    内存区的每一个字节都有一个编号,这就是“地址”
    指针的实质就是内存“地址”,指针就是地址,地址就是指针

    指针就是内存单元的编号
    指针变量就是存放内存单元编号的变量,或者说指针变量就是存放地址的变量,指针和指针变量是两个不同的概念

    也可这样理解:

    编号(地址):内存中每一个字节分配一个号码
    定义一个变量,存放上面的号码,这样的变量叫做指针变量

    但是要注意:通常我们叙述时会把指针变量简称为指针,实际它们含义并不一样。指针的本质就是一个操作受限的非负整数

2、彻底理解C指针

 

#include <stdio.h>

void text02()
{
    int num=100;
    //取变量的地址,用&
    //&num代表num的起始地址
    printf("%p\n",&num);   //008FF9EC

    //需求:定义一个指针变量(系统会给这个变量开通4字节的空间),保存num的地址
    //在定义的时候:*p说明p是指针变量,而不是普通变量    //int * p 等价于 int *p 也等价于 int* p
    int * p=NULL;
    printf("sizeof(p)=%d\n",sizeof(p));  //sizeof(p)=4

    //num的地址 与p 建立关系
    p = &num;  

    printf("num = %d\n",num);  //num=100
    //在使用中:*p表示取p保存的地址对应空间里的内容
    printf("*p = %d\n",*p);    //*p=100
}

void test03()
{
    int num = 10;

    //指针变量两种类型:自身的类型、指向的类型
    //自身的类型:在指针变量定义的时候 将变量名拖黑 剩下啥类型 指针变量就是啥类型
        //p自身的类型就是 int *
    //指向的类型:在指针变量定义的时候 将变量名和离它最近的一个*一起拖黑 剩下的啥类型 指针变量指向的就是啥类型
       //p的指向类型是int

    //指针变量指向的类型的作用:决定了指针变量所取空间内容的宽度 决定了指针变量+1跳过的单位跨度
    int *p = NULL;
    p = &num;

    //指针变量的跨度
    //%u表示无符号的打印
    printf("&num=%u\n",&num);    //&num=1638128
    printf("p=%u\n",p);         //p=1638128
    printf("p+1=%u\n",p+1);  // p+1=1638132
}

void text04()
{
    int num=0x01020304;//16进制中每两位代表一个字节

    int *p1 = &num;

    printf("*p1 = %#x\n",*p1); //*p1 = 0x1020304
    //%#表示的输出提示方式,如果是8进制,在前面加0,如果是十进制,不加任何字符,如果是十六进制,会加上0x
}

int main(int argc,char *argv[])
{
    //text02();
    //test03();
    text04();

    return 0;
}

3.指针常见错误

# include <stdio.h>

int main(void)
{
    int i = 5;
    int * p;
    int * q;

    p = &i;
    //*p = i;//error  p没有指向
    //*q = p; //error 语法编译会出错,*q 为int类型,p为int * 类型
    //*q = *p;  //error
    p = q;  //q是垃圾值,q赋给p, p也变成垃圾值
    printf("%d\n", *q);   //13行
        /*
            q的空间是属于本程序的,所以本程序可以读写q的内容,
            但是如果q内部是垃圾值,则本程序不能读写*q的内容
            因为此时*q所代表的内存单元的控制权限并没有分配给本程序
            所以本程序运行到13行时就会立即出错
        */
    return 0;
}

4.经典指针程序--互换两个数字

# include <stdio.h>

void swap_1(int , int);
void swap_2(int *, int *);
void swap_3(int *, int *);

int main(void)
{
    int a = 3;
    int b = 5;

    swap_3(&a, &b); //swap_2(*p, *q); 是错误的, swap_2(a, b);也是错误的
    printf("a = %d, b = %d\n", a, b);

    return 0;
}

//不能完成互换功能
void swap_1(int a, int b)
{
    int t;

    t = a;
    a = b;
    b = t;

    return;
}

//不能完成互换功能:这个函数相当于把ab的地址互换了,值没有互换
void swap_2(int * p, int * q)//形参名是p和q,接受实参数的是p和q
{
    int * t;//如果要互换p和q的值,则t必须是int *,不能是int,否则会出错

    t = p;
    p = q;
    q = t;
}

//可以完成互换功能
void swap_3(int * p, int * q)
{
    int t; //如果要互换*p和*q的值, 则t必须定义成int,不能定义成int *, 否则语法出错

    t = *p;  //p是int *,  *p是int
    *p = *q;
    *q = t;
}

5、通过被调函数修改主调函数普通变量的值

  i) 实参必须为该普通变量的地址

  ii) 形参必须为指针变量

  iii) 在被调函数中通过 *形参名 = ... 的方式就可以修改主调函数相关变量的值

# include <stdio.h>

int f(int i, int j)
{
    return 100;
//    return 88;
}

void g(int * p, int * q)
{
    *p = 1;
    *q = 2;
}

int main(void)
{
    int a = 3, b = 5;
    g(&a, &b);
    printf("%d %d\n", a, b);
    return 0;
}

补充:

1.cpu和内存之间有三根主线:控制总线、数据总线、地址总线:32位

2.*的含义:

//1.乘法
//2.定义指针变量
    int*p;// 定义了一个名字叫p的变量,int*表示p只能存放int变量的地址
//3.指针运算符
  该运算符放在已经定义好的指针变量的前面   如果p是一个已经定义好的指针变量   则 *p 表示以p的内容为地址的变量         

原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/12638575.html

时间: 2024-10-10 17:44:08

1、指针(理解、使用)的相关文章

[c++]this指针理解

#include <iostream> using namespace std; /** * this 指针理解 */ class A{ int i; public: void hello(){ cout<<"Hello"<<endl; } }; int main(){ A *p=NULL; p->hello(); } 由于单独开发基于c++的编译器,c++程序翻译成c程序后在,在使用c语言的编译器进行编译. p->hello(); 翻译

关于this指针理解

1. this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果.this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数.也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行.  例如,调用date.SetMonth(9) <===> SetMonth(&date, 9),this

c/c++指针理解

指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址.要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区.让我们分别说明. 先声明几个指针放着做例子: 例一: int *ptr; char *ptr; int **ptr; int (*ptr)[3]; int *(*ptr)[4]; 指针的类型 从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型.这是指针本身

指针理解

内存分布 内存地址 1x01 1x02 1x03 1x04 1x05 变量 5   &a(1x01)     定义一个变量: int a: 在内存上开辟了一块地方,“a”是他的名字,他在内存上的编号是1x01: 给 a 赋值: a =  5: 在内存编号为1x01 的地方存储了 “5“,如上图: 定义一个指针: int *p: 在内存上开辟了一块地方,“p” 为他的名字,他在内存上的编号是1x03: 给p赋值: p = &a:p的内存存储的是a的内存地址: 下图详细的介绍了指针的原理: 几

PHP文件操作函数及文件指针理解

知识点: 一.fopen(),文件打开函数,读写参数有: 1.R  : 只读,指针在文件开头 2.r+:读写,指针同上 3.W :只写,写入前会删除文件内容,然后指针回到文件开头,文件不存在则创建 4.w+: 读写,其他同上 5.A: 只写,指针在文件末尾,文件不存在则创建,注意:此模式为"追加" 6.a : 读写, 同上 7.x:创建并打开文件(方式:只写),如果文件已存在,则返回一个E_warning错误 8.x+:创建并打开文件(方式:读写),其他同上 总结:R方式读写不错,W会

C语言指针理解patr1

今天在看<Head First C语言>中,书中的代码是*lat=*lat+1;我则写成了*lat++:结果是并不能得到lat指针的内容加一.之后发现原来在C语言中*解指针运算符 与++后自增运算符的优先级是相同的,*p++,后自增运算符++只作用于p,并不能作用于*p(如果*的优先级更高的话才行). 之后在调试中又发现了一个之前不了解的地方,在C语言中栈的存储是向低地址扩展,也就是先声明的变量在内存中反而内存地址是更大的. 1 #include <stdio.h> 2 void

C语言指针理解,记下来以后看

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址. 要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的 类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区.让我们分别说明.  先声明几个指针放着做例子:  例一:  (1)int*ptr;  (2)char*ptr;  (3)int**ptr;  (4)int(*ptr)[3];  (5)int*(*ptr)[4];    指针的类型  从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部

程序的思考之一个可以检验你指针理解功力的程序

希望结果可以不让你大吃一惊哟!小程序也可以大智慧的! #include<iostream> using namespace std; int main() { double* (*a)[3][6]; cout<<sizeof(a)<<endl; //4 a就是一个数组指针32位下是4字节 cout<<sizeof(*a)<<endl; // 72 *a就是数组整体 cout<<sizeof(**a)<<endl; // 2

C语言复杂指针理解

学习和使用C语言近十年了但对C语言的复杂指针依然有些迷糊索性花点时间分析一下,下面是一些心得,希望对读者有所帮助 取The C Programming Language中的两个例子以分析 char (*(*x())[])(); char (*(*x[3])())[5]; 若直接让我们说出这两个x分别是什么意思往往会有一些困难, 这里我们可以使用代入法(暂且叫代入法)来分析 分析结果转述原则: 左端=右端(比如下面的Y=*x()中Y为左端, *x()为右端) 若右端为数组则左端可被看作右端的其中一

C开发系列-指针理解

指针 #include <iostream> using namespace std; void changeValue(int n) { n = 10; } int main(int argc, char *argv[]) { int num = 1; changeValue(num); cout << num << endl; // 这里输出num = 1 return 0; } 原文地址:https://www.cnblogs.com/CoderHong/p/89