C基础课程笔记总结7-指针1

课程:指针

指针,在OC使用非常频繁,指针是非常重要的一个知识点,必须完全掌握,但在实际编程开发中,所涉及的指针知识并不会太深,例如N维数组指针。

任何变量都有所属类型,指针变量也是变量,因此声明指针变量时也必须声明变量类型,声明类型的主要目的是为了在操作指针移动时,可以正确定义每次移动的字节数是多少,

不同的数据类型在内存中所占的字节数是不同的。

在声明指针变量时,用“*”号来标识这个变量是一个指针变量,而指针变量名中是不包括“*”号的,要给指针变量赋值,必须是赋予内存地址的值

使用printf()输出打印某个变量的地址值时,要用 %p  来接收地址(),实际上”p“表示接收的数值是一个16进制表示的数值,如果改用”%d“接收的话,会将传入的16进制数值转换为十进制数字输出显示。

问题:

1.在C中,是否地址值都有特殊的标识来表明这个值是一个地址值???

2.如果得到一个内存地址实际的值后,将该值赋值给一个int 变量,然后将Int 变量的值直接赋值给指针,是否有语法错误??

回答:

int change(int *p) ;


void main()
{
    int a=0xfff2;
    int b=16   ;
    int *p;
    p=a;
    printf("&a=%p,&b=%p,b=%d,p=%p,*p=%d\n",&a,&b,b,p,*p);
    change(p);
    printf("*p=%d,a=%d,b=%d\n",*p,a,b);
    getchar();


}


int change(int *p)
{
    *p=100;
    return *p;
}


答1:通过这个检测的小程序可以看出,指针变量传入的一切数值当成地址去理解,不论十进制或是十六进制,或是通过取地址符号"&"传入数值,都当成接收了一个地址值,在编译器中,并没有任何特殊的标识符去标识一个值是特指地址值,只要是值,都能够被当成地址值传递,因此,在使用地址是需要非常仔细,否则可能会出现及其难以找出的错误。

答2:完全可以,但必须保证该值正确指向了所想要指向的地址,否则容易出现未知错误,即使传入的不是十六进制的数值,系统也会自动将数值转换为十六进制的。归根结底,系统最终会将一切数值转为0和1.


只要是变量,在内存空间中都会占有自己的一个地址,指针变量也是变量,他也有自身的地址,只不过指针变量所存储的值是另一个变量的所在内存的地址,通过这个地址,可以指向另一个变量,一个指针变量所占内存字节数为8个,不论该指针是指向什么数据类型,在64位编译环境下,都是占用8个字节


*号,在声明变量时表示该变量是一个指针变量,在使用指针变量时,在指针 变量名前加上*号表示该指针变量所指向的地址所存储的数值,如果只是单独的指针变量名,则表示该变量中存储的值可以被当成一个地址看待,*号只能作用于定义为指针变量的变量,其他变量无法使用*号来指向另一个变量。


问题:视频中所举例子:地址传递可以改变变量的值,而值传递不能改变变量的,原因是值传递创造了两个内存区域,用于存储不同函数中的变量值,假如定义了一个全局变量呢?通过值传递是否可以改变变量的值。


指向指针变量的指针:

声明如下: 

int *p

int a=10;

p=&a;

int **p1;                           //指针变量的声明格式:x *p;表明指针变量的类型是(x *),可以这样理解,其中x = int char double 等等;一定要写两个**号吗????



小技巧:定义变量是,在变量名之前的全都表示这个变量的变量类型,对于多重指针,本质还是指向一个变量的指针,不同的是指向什么类型变量的指针,只需要将变量类型之后在加上“*”号定义,则说明该指针变量指向了某个变量类型的变量,因此,N重指针有N个“*”号。


在实际开发中,2重以上指针并不常使用,平均大概每半年左右需要一次多重指针,常见的的一级指针使用,多重指针问题,归根结底是指向关系问题,我指向你,你指向他,他又指向另一个他,不断延伸。例如:

int a=10;

int *p;

int **pp;

p=&a;

*p=a;

*pp=&p;

**pp=*p=a;

*pp=p=&a;


任何函数都只能返回一个值,但是可以通过设置参数为变量的地址,在函数运行的过程中直接改变地址所指向的变量的值,而不需要通过返回值来进行赋值运算。

通过指针,相当于可以使得一个函数有无限个返回值,实际上该函数内部也会产生N个指针用于接收所传递的地址参数。


指向不同类型变量,需要定义相对应类型的指针变量,尽管每个指针变量所占的内存字节数都是8个,但在×p操作时,是根据所指向的不同类型的数据所占字节数去进行取值操作的,指针变量中所存放的地址实际上是变量所占内存字节块(即多个连续的字节数所组成的一个块,例如int 类型,占4个字节,那么指针变量中的值只是这个4个字节地址中的第一个字节的地址),当进行*p取值操作时,按照所指向的数据类型的字节数多少,从首地址开始,继续往下取出内存字节中所存储的数据,合并起来构成一个完整的数据。例如char *p,int *p,字符指针只会取一个字节中的内容,而整数指针会依次取4个字节的内容之后合并数据。赋值操作也是一样的过程步进++,+1的操作也是一样。

对于占多个内存字节的变量而言,首地址是所占字节中低地址的字节,指针有该变量的内存字节块中,从低地址向高地址字节取值。

然而在定义变量时,先定义的变量根据系统的不同,有的系统先存放在高地址字节中,有的先存放在低地址字节中,但是对于所存储的数值,都是把低位的数,即最右边的数放在低地址字节中存储,即首地址存放的是低位的8个数字,依次往后推(是否不同系统也不同?)

数组与指针:

在OC中,涉及得并不深。

数组名是该数组的地址,也是该数组首元素的地址,即数组首元素的地址就是该数组的地址,当指针指向一个数组时,即把数组名的值给了指针,因此在这个关系中,数组等于指针,指针等于数组,他们是可以混用的,例如:

int  arrary[2]={1,2};int *p=array;p[1]=array[1]=2;

 在函数中将参数定义为数组,在传递数组时,编译器会自动将所传的数组转为指针,因此在该函数中,传递的并不是真正的整个数组,而只是这个参数的地址而已,传入的是什么地址,就以什么地址为基准,在这个函数中,SIZEOF(数组)永远只是8个字节,因为指针就是8个字节。

但在OC中,利用指针操作数组并不常用,在OC中有自己的数组。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值