精华内容
下载资源
问答
  • 关于c语言中指针的一些理解这几天在看任哲老师编写的嵌入式实时操作系统uC/OS原理与应用一书,第二章讲到指针的用法,我发现自己有些地方有疑问,就重新看了关于c指针的知识。同时也对指针有了一定的理解。在理解...

    关于c语言中指针的一些理解

    这几天在看任哲老师编写的嵌入式实时操作系统uC/OS原理与应用一书,第二章讲到指针的用法,我发现自己有些地方有疑问,就重新看了关于c指针的知识。同时也对指针有了一定的理解。

    在理解指针的时候我们一定要将他跟内存地址联系起来,这也是c语言跟c++的区别,c语言可以更接近硬件底层。对于指针我们可以理解为其是一个存放内存地址的变量。*跟&,*是声明一个指针变量,而&是创建一个引用。

    我们现在定义一组声明:

    int  a=112,b=-1;

    float  c=3.14;

    int  *d=&a;

    float  *e=&c;

    a4c26d1e5885305701be709a3d33442f.png

    对于以上的声明,我们可以用如图这种方式来表达,每一个小格代表一个内存地址,我们这里定义两个字节为一个字。100,102,104,106,108这五个整数为地址,我们定义a,b,c,d,e为其地址名字,这样我们可以通过名字访问内存地址而不是具体的数字。这些变量名也让我们更加方便的去访问内存地址。

    在这些声明中,变量a,b用于存储整型变量,而c用于存储浮点型变量,d和e里边存的是a跟b的地址而不是内容(这点需要我们牢记)d的地址是106内容是100(也就是a的地址)。我们不能理解为变量d和e的值就是112跟3.14。d和e被声明为指针并不能改变这些表达式的求值方式。也就是说指针型变量有两点不同于整型变量,一是他对应地址存的内容,二是他的求值方式,不会因为他是指针型变量就将其内容改变为所指变量里的内容。如果你简单的理解为他是指针,所以可以自动的获得存储于位置100和104的值,那么你就错了。变量的值就是分配给该内存位置所储存的数值,即使是指针也不例外,只是不同的是他们求值方式会不同。

    通过一个指针访问他所指向的地址的过程称为间接访问。用于执行间接访问的操作符是单目操作符*。

    a4c26d1e5885305701be709a3d33442f.png

    对于上图所示d的值为100,。当我们使用了间接访问操作符时,他表示访问内存位置100并查看那里的值,因此*d的右值为112——位置100的内容,他的左值是位置100本身。间接访问操作符需要的是个右值,但这个操作符所产生的结果是个左值。指针变量之所以可以作为左值,不是因为他们是指针,而是因为他们是变量。对指针变量进行间接访问表示我们应该访问指针所指向的位置。

    我们来看一个表达式:

    *&a=25,

    这个表达式的意思是将25赋值给a。我们来分析这个表达式。&a表示取a的地址。他是一个指针常量(使用这个指针常量并不需要知道的实际值,因为a我们已经定义了此内存地址的名字。*操作符访问其操作数所表示的地址。在这个表达式中*的操作数是a的地址,所以25直接存于a所对应的那个内存空间中。

    我们接下来看指针的指针

    int  a=12;

    int  *b=&a;

    c=&b;

    c我们定义的是一个指针,这个指针是指向b这个指针的指针,而它所指向的那个指针是一个指向整形的指针。

    1.int *p;

    2.int **p;

    3.int *p[10];

    4.int (*p)[10];

    5.int *p(int);

    6.int (*p)(int);

    7.int (*p[10])(int);

    对于上述的7条分别是:

    1.指向整型的指针

    2.指向指针的指针,而他所指向的指针是一个指向整型变量的指针

    3.一个有10个指针的数组,这十个指针分别指向十个整型变量

    4.一个指针,指向有十个整型数据的指针

    5.一个函数(不是函数指针),函数有一个整型参数,返回值是一个指向整型的指针

    6.函数指针,该函数有一个整形参数,返回值是一个整型类型

    7.一个有十个指针的数组,该数组中的指针指向一个函数,该函数有一个整型参数并返回一个整型数

    展开全文
  • 通过一个例子引出对指针的概念理解1,例子#includeint main(void){int xiaozhang = 178; //小张的身高int xiaoli = 175; //小李的身高int xiaowang = 179; //小王的身高int *xiaolin,*xiaohong;xiaolin= &...

    通过一个例子引出对指针的概念理解

    1,例子

    #include

    int main(void)

    {int xiaozhang = 178; //小张的身高

    int xiaoli = 175; //小李的身高

    int xiaowang = 179; //小王的身高

    int *xiaolin,*xiaohong;

    xiaolin= &xiaozhang; //小玲指向小张

    xiaohong = &xiaowang; //小红指向小王

    printf("小玲喜欢的人的身高:%d",*xiaolin);

    printf("小红喜欢的人的身高:%d",*xiaohong);

    xiaohong= &xiaoli; //小红指向小李(移情别恋)

    *xiaohong = 180; //将小红指向的对象赋为180 == 修改小红喜欢的人的身高

    printf("");

    printf("小张的身高:%d",xiaozhang);

    printf("小李的身高:%d",xiaoli);

    printf("小王的身高:%d",xiaowang);

    printf("小玲喜欢的人的身高:%d",*xiaolin);

    printf("小红喜欢的人的身高:%d",*xiaohong);return 0;

    }

    fa017fc32160c4caf06a525e30ec0c55.png

    2,理解

    当指针p的值为对象x的地址时,我们一般会说“p指向x”。

    通过以上例子,我们在这里可以将“指向”理解成“喜欢”,因此,指针p的值为对象x的地址我们可以理解成“p喜欢x”。

    接着进行“xiaohong = &xiaoli”的复制,我们就可以得出“小红喜欢小李”。

    559a135e7787e500bb3f80a1862fbcc5.png

    xiaolin、xiaohong的数据类型是“指向int型变量的指针型”

    xiaolin = &xiaozhang;

    xiaohong= &xiaowang;

    从以上赋值语句也可以发现,&xiaozhang、&xiaowang的类型也是“指向int型变量的指针型”。

    所以说取地址符(&)不光可以理解为取址运算符,也可以理解为生成指针,表达式&xiaozhang是指向xiaozhang的指针,其值为xiaozhang的地址。

    指针运算符

    在进行显示的地方,就要用到叫作指针运算符的单目运算符*。

    将指针运算符*写于指针之前,就可以显示该指针指向的对象内容。

    e91f68aca716dbb0853ae6242fd4b288.png

    因此,*xiaolin就等于“xiaolin指向的对象”,*xiaolin就是xiaozhang。*xiaolin是xiaozhang的别名。

    所以当p指向x时,*p就是x的别名。

    指针运算符的赋值

    当指向 xiaoli 的指针赋给xiaohong,使 xiaohong 指向 xiaoli,这样一来就变成“xiaohong 喜欢 xiaoli”

    小红从小王移情别恋给小李了,啧啧...

    所以,如果将指向其他对象的指针赋给指针变量,那么该指针变量就会指向这些对象。

    因此,上例的程序运行结果如下

    xiaolin = &xiaozhang;

    xiaohong= &xiaowang;

    printf("小玲喜欢的人的身高:%d",*xiaolin);

    printf("小红喜欢的人的身高:%d",*xiaohong);

    xiaohong= &xiaoli; //int 175

    *xiaohong = 180; //修改小李的身高,从175变为180

    printf("");

    printf("小张的身高:%d",xiaozhang);

    printf("小李的身高:%d",xiaoli);

    printf("小王的身高:%d",xiaowang);

    printf("小玲喜欢的人的身高:%d",*xiaolin);

    printf("小红喜欢的人的身高:%d",*xiaohong); //输出180

    展开全文
  • C语言中指针理解1:指针是什么1.C语言中指针是什么1.1 指针变量和普通变量的区别1.2 为什么需要指针1.3 指针使用的标准方式2.指针带来的一些符号的理解2.1 星号*2.2 取地址符&2.3 指针定义并初始化与指针...

    1.C语言中的指针是什么

    1.1 指针变量和普通变量的区别

    首先必须非常明确:指针完整的名字应该叫指针变量,简称为指针。指针的实质就是个变量,从内存和数据的角度来说,它跟普通变量没有任何本质区别。

    来看下面一段代码:

    #include<stdio.h>
    
    int main(int argc,char**argv)
    {
    	int a=5;
    	int* p=&a;
    	printf("a = %d,p = %p.\n",a,p);
    	return 0;
    }
    

    运行结果:

    a = 5,p = 0x7ffe97237f6c.
    

    以64位机器为例,来分析一下对于上面的代码编译器会做哪些工作:

    • 对于int a=5;,编译器会在内存中找一个4个字节的内存空间,然后把这个空间和符号a绑定起来,之后操作a就等于操作这个内存空间,再将数值5以二进制补码的形式存放到这片空间当中去。
    • 同样的对于int* p=&a;,编译器会在内存中找一个8个字节的空间,把这段空间和符号p绑定起来,再将变量a的地址存放到这片空间中去。

    通过上面的分析可以知道,其实不管是int a还是int* p,编译器做的事情实际上是没有区别的:都是在内存中分配一段空间,将这个空间和一个符号绑定,然后往该空间内赋上指定的数据

    指针变量和其他非指针普通变量的区别是:指针变量内部存储的数据应该是另一个普通变量(包括指针变量)的地址。就好像我们买了2个桶apa用来放水,p用来放盐,本质上ap是没有区别的,它们都是桶,都可以用来存放东西,区别就是各自应当放入的东西是不一样的。

    1.2 为什么需要指针

    指针的出现是为了实现间接访问。在汇编语言中也有间接访问,这其实就是在计算机组成原理课程中CPU寻址方式中的间接寻址。CPU的间接寻址是CPU设计时决定的,这也决定了汇编语言必须能够实现间接寻址,从而又决定了汇编之上的C语言也必须实现间接寻址。

    尽管高级语言如JavaC#等没有指针,但是语言本身封装实现了间接访问。

    1.3 指针使用的标准方式

    指针使用的三部曲:

    • 1.定义指针变量。
    • 2.关联指针变量,其实就是给指针变量赋值,让它指向另一个变量,没有关联之前,这个指针不能被解引用。
    • 3.对指针变量解引用,通过指针访问它指向的变量。

    举个栗子:

    #include<stdio.h>
    
    int main(int argc,char**argv)
    {
    	int a=5;
    	
    	//1.定义指针变量
    	int* p;
    	
    	//2.关联指针变量,将a的地址赋值给p,让p指向a
    	p=&a;
    
    	//3.对指针变量解引用
    	printf("*p = %d.\n",*p);
    	return 0;
    }
    

    单纯的使用int * p;定义一个指针变量p而不通过赋值符号初始化时,因为p是局部变量,所以也遵循C语言局部变量的一般规律:定义局部变量并且未初始化则值是随机的,所以此时p变量中存储的是一个随机的数字。此时如果解引用p,则相当于我们访问了这个随机数字为地址的内存空间。那这个空间到底能不能访问不知道,也许行也许不行,所以如果直接定义指针变量未绑定有效地址就去解引用几乎一定会导致错误。

    因此定义一个指针变量,不经绑定有效地址就去解引用,就好像拿一个上了镗的枪随意转了几圈然后开了一枪。指针绑定的意义就在于:让指针指向一个可以访问并且应该访问的地方,就好象拿着枪瞄准目标的过程一样;指针的解引用是为了间接访问目标变量,就好象开枪是为了打中目标一样。

    2.指针带来的一些符号的理解

    2.1 间接访问操作符 *

    C语言中*可以表示乘号,也可以表示与指针相关的操作符。这两个用法是毫无关联的,只是恰好用了同一个符号而已。

    星号在用于指针相关功能的时候有2种用法:

    • 第一种是指针定义时,*结合前面的类型(如intchar)用于表明要定义的指针的类型。
    • 第二种功能是指针解引用,例如对于指针变量p解引用时,*p表示p指向的变量本身。

    2.2 取地址符&

    取地址符使用时直接加在一个变量的前面,然后取地址符和变量加起来构成一个新的符号,这个符号表示这个变量的地址,可以作为右值赋给指针变量。例如&a得到的就是变量a的地址。

    2.3 指针定义并初始化与指针定义然后赋值的语法区别

    指针变量定义时可以初始化,指针的初始化其实就是给指针变量初值,跟普通变量的初始化没有任何本质区别。

    指针变量定义同时初始化的语法是:

    int a = 32; 
    int *p = &a;
    

    指针变量定义时不初始化之后再赋值的语法是:

    int a = 32; 
    int *p; 	
    p = &a;	//正确
    *p = &a;//错误,*p表示p指向的变量
    

    2.4 左值与右值

    放在赋值运算符=左边的就叫左值,右边的就叫右值。所以赋值操作其实就是:

    左值 = 右值;
    

    当一个变量做左值时,编译器认为这个变量符号的真实含义是这个变量所对应的那个内存空间。当一个变量做右值时,编译器认为这个变量符号的真实含义是这个变量的值,也就是这个变量所对应的内存空间中存储的那个数。

    左值与右值的区别,就好象现实生活中"家"这个字的含义。比如说"我回家了",这里面的家指的是你家的房子,类似于左值;但是说"家比事业重要",这时候的家指的是家人,就是住在家所对应的那个房子里面的人,类似于右值。

    3.野指针问题

    3.1 什么是野指针

    野指针就是指针指向的位置是不可知的、随机的、不正确的、没有明确限制的。野指针很可能触发运行时段错误(Sgmentation fault),因为指针变量在定义时如果未初始化,它的值是随机的。指针变量的值其实就是别的变量(指针所指向的那个变量)的地址,野指针意味着这个指针指向了一个地址是不确定的变量,这时候去解引用就是去访问这个地址不确定的变量,所以结果是不可知的,很可能会导致错误。

    野指针因为指向地址是不可预知的,所以有3种情况:

    • 第一种是指向普通程序不可访问的地址,操作系统不允许访问的敏感地址,比如内核空间。结果是触发段错误,这种算是最好的情况了,因为会报错,可以及时发现并解决。
    • 第二种是指向一个可用的但是没什么特别意义的空间,比如曾经使用过但是已经不用的栈空间或堆空间,这时候程序运行不会出错,也不会对当前程序造成损害,但是这会掩盖程序错误,让程序员以为程序没问题,其实是有问题的。
    • 第三种情况就是野指针恰好指向了一个可用的空间,而且这个空间其实正在本程序中正在被使用,比如程序的一个变量a,那么野指针的解引用就会刚好修改这个变量x的值,导致这个变量莫名其妙的被改变,程序出现离奇的错误,一般最终都会导致程序崩溃,或者数据被损害,这种危害是最大的。

    指针变量如果是局部变量,则分配在栈上,本身遵从栈的规律:反复使用,使用完不擦除,所以是脏的,本次在栈上分配到的变量的默认值是上次这个栈空间被使用时余留下来的值,就决定了栈的使用多少会影响这个默认值。因此野指针的值是有一定规律不是完全随机,但是这个值的规律对我们没意义,因为不管落在上面野指针3种情况的哪一种,都不是我们想看到的。

    3.2 如何避免野指针

    野指针的错误来源就是指针定义了以后没有初始化,也没有赋值,总之就是指针没有明确的指向一个可用的内存空间就去解引用。

    知道了野指针产生的原因,避免方法就出来了:在指针的解引用之前,一定确保指针指向一个绝对可用的空间。常规的4点做法是:

    • 1.定义指针时,同时初始化为NULL
    • 2.在指针解引用之前,先去判断这个指针是不是NULL
    • 3.指针使用完之后,将其赋值为NULL
    • 4.在指针使用之前,将其赋值绑定给一个可用地址空间。

    野指针的防治方案4点绝对可行,但是略显麻烦,很多人懒得这么做。在中小型程序中,自己水平可以把握的情况下,不必严格参照这个标准。但是在大型程序,或者自己水平感觉不好把握时,建议严格参照这个方案。

    3.3 NULL是什么

    NULLC/C++中定义为:

    #ifdef _cplusplus			// 定义这个符号就表示当前是C++环境
    #define NULL 0				// 在C++中NULL就是0
    #else
    #define NULL (void *)0		// 在C中NULL是强制类型转换为void *的0
    #endif
    

    C语言中,int *p;之后可以p = (int *)0;但是不可以p = 0;因为类型不相同。

    所以NULL的实质其实就是0,只不过这个0代表的是地址,而不是一个整数,然后我们给指针赋初值为NULL,其实就是让指针指向0地址处。指向0地址处有2个原因:

    • 第一层原因是:0地址处被认为是一个特殊地址,指针指向这里就被认为指针没有被初始化,就表示是野指针。
    • 第二层原因是:0地址在一般的操作系统中都是不可被访问的,如果C语言程序员不按规矩(不检查是否等于NULL就去解引用)写代码直接去解引用就会触发段错误,程序员就可以发现问题然后去解决,这样的结果已经是最好的结果了。

    一般在判断指针是否野指针时,都写成

    if (NULL != p)
    

    而不是写成

    if (p != NULL)
    

    原因是:如果NULL写在后面,当中间是==号的时候,有时候容易写错写成了=,这时候其实程序已经错误,但是编译器不会报错。这个错误(对新手)很难检查出来。但是如果习惯了把NULL写在前面,当错误的把==写成了=时,编译器会报错,程序员就可以发现这个错误。

    4.const与指针的合用

    4.1 const修饰指针的4种形式

    const关键字在C语言中用来修饰变量,表示这个变量是常量。指针变量也是变量,所以const关键字自然也可以用来修饰指针。

    const修饰指针常见的有4种形式,区分清楚这4种即可全部理解const和指针。以int类型指针为例:

    • 第一种:const int *p;,表示p本身不是const*pconst
    • 第二种:int const *p;,表示p本身不是const*pconst
    • 第三种:int * const p;,表示p本身是const*p不是const
    • 第四种:const int * const p;,表示p本身是const*p也是const

    关于指针变量的理解,主要涉及到2个变量:第一个是指针变量p本身,第二个是p指向的那个变量,也就是*p。一个const关键字只能修饰一个变量,所以弄清楚这4个表达式的关键就是搞清楚const放在某个位置是修饰谁的。

    4.2 const修饰的变量真的不能改吗

    gcc环境下,const修饰的变量其实是可以改的。在某些单片机环境下,const修饰的变量是不可以改的。const修饰的变量到底能不能真的被修改,取决于具体的环境,C语言本身并没有完全严格一致的要求。

    gcc中,const是通过编译器在编译的时候执行检查来确保实现的(也就是说const类型的变量不能改是编译错误,不是运行时错误。)所以我们只要想办法骗过编译器,就可以修改const定义的常量,而运行时不会报错。更深入一层的原因,是因为gccconst类型的常量也放在了data段,其实和普通的全局变量放在data段是一样实现的,只是通过编译器认定这个变量是const的,运行时并没有标记const标志,所以只要骗过编译器就可以修改了。

    4.3 const究竟应该怎么用

    const是在编译器中实现的,在代码编译时检查,因此运行时并非不能骗过。所以在C语言中使用const就好象是一种道德约束而非法律约束,所以使用const时更多是传递一种信息,就是告诉编译器,也告诉读程序的人,这个变量是不应该也不必被修改的。

    展开全文
  • C语言中指针详解

    千次阅读 2021-11-01 14:12:21
    C语言中指针是一种数据类型,指针是存放数据的内存单元地址。 计算机系统的内存拥有大量的存储单元,每个存储单元的大小为1字节,为了便于管理,必须为每个存储单元编号,该编号就是存储单元的“地址”,每个存储...

    1. 什么是指针

    C语言中指针是一种数据类型,指针是存放数据的内存单元地址。

    计算机系统的内存拥有大量的存储单元,每个存储单元的大小为1字节,为了便于管理,必须为每个存储单元编号,该编号就是存储单元的“地址”,每个存储单元拥有一个唯一的地址。

    指针变量除了可以存放变量的地址外,还可以存放其他数据的地址,例如可以存放数组和函数的地址。

    2. 指针的定义和初始化

    格式:数据类型符 *指针变量名[=初始地址值]。

    功能:定义指向“数据类型符”的变量或数组的指针变量,同时为其赋初值。

    定义说明:

    1. “*” 表示定义的是一个指针变量,指针变量的前面必须有 “*” 号;

    2. 在定义指针变量的同时也可以定义普通变量或数组等其它变量;

    3. “数据类型符” 是指针变量所指向变量的数据类型,可以是任何基本数据类型,也可以是其他数据类型;

    4. “初始地址值” 通常是 “&变量名” “&数组元素” 或 “一维数组名”,这里的变量或数组必须是已定义的;

    5. 在定义指针变量时,可以只给部分指针变量赋初值;

    6. 指针变量的初始化,除了可以是已定义变量的地址,也可以是已初始化的同类型的指针变量,也可以是NULL(空指针);

    7. 指针变量初始化时,指针变量的“数据类型符”必须与其“初始地址值”中保存的数据的类型相同;

    8. 不能用auto类型的地址去初始化static型指针。

    3. 指针变量的使用

    1. 给指针变量赋值

    格式:指针变量=地址型表达式

    “地址型表达式”即运算结果是地址型的表达式。C语言规定,变量地址只能通过取地址运算符获得,即“&”,其运算对象是变量数组元素名,运算结果是对应变量或数组元素的地址。

    需要注意的是,虽然地址是一个整数,但是C语言中不允许把整数看成“地址常量”,所以此处的“地址型表达式”不能是整数。

    2. 使用指针变量

    格式:指针变量名

    需要使用地址时,可以直接引用指针变量名。

    3. 通过指针变量引用所指向的变量

    格式:*指针变量名

    “*指针变量名” 代表其指向的变量或数组元素,其中的“*”称为指针运算符。需要注意的是,这种引用方式要求指针变量必须已经定义且有值。

    4. 指针的基本运算

    1. 取地址运算符 &

    取地址运算符“&”的功能是取变量的地址,它是单目运算符。取地址运算符的运算对象必须是已经定义的变量或数组元素,但不能是数组名。运算结果是运算对象的地址。

    2. 指针运算符 *

    指针运算符“*”的功能是取指针变量所指向地址中的内容,与取地址运算符“&”的运算是互逆的,它是单目运算符。指针运算符的运算对象必须是地址,可以是已赋值的指针变量,也可以是变量或数组元素的地址,但不能是整数,也不能是非地址型的变量。运算结果就是地址对应的变量。

     取地址运算符和指针运算符的优先级和结合性:

    1. 取地址运算符、指针运算符和自增、自减等单目运算符的优先级相同;

    2. 所有单目运算符的结合性为从右至左。

    5. 指针的算术运算

    指针变量可以进行的算术运算包括:

    1. 指针变量 ± 整数;

    2. 指针变量++ ++指针变量;

    3. 指针变量-- --指针变量;

    4. 指针变量1- 指针变量2;

    由于指针运算符*与自增运算符++、自减运算符--的优先级相同,结合方向都是从右至左,因此需要注意以下各种形式的含义不同。

    6. 指针的关系运算

    两个类型相同的指针变量可以运用关系运算符比较大小,表示两个指针变量所指向地址位置的前后关系,即:前者为小,后者为大

    需要注意的是,如果两个指针变量不是指向同一个数组,则比较大小没有实际意义。

    7. 指针变量的引用

    1. 通过指针变量访问整型变量

    2. 指针变量作为函数参数

    普通变量作为函数的参数传递时是按值传递,实参与形参不共享内存。指针变量作为函数参数时是地址传递,共享内存,“双向传递”。

    以下是按值传递的情况:

     以下是按地址传递的情况:

    8. 指针和数组

    数组的指针是指向数组在内存的起始地址,数组元素的指针是指向数组元素在内存的起始地址。

    1. 当指针变量指向一维数组,可以采用以下两种方法:

    (1). 在数据定义语句中用赋初值的方式:*指针变量=数组名;

    (2). 在程序中用赋值的方式:指针变量=数组名;

    2. 当指针变量指向一维数组元素,可以采用以下两种方法:

    (1). 在数据定义语句中用赋初值的方式: *指针变量=&数组名[下标];

    (2). 在程序中用赋值的方式: 指针变量=&数组名[下标];

    3. 当指针变量指向一维数组,利用指针变量引用一维数组元素的方法如下:

    (1). 引用下标为0的数组元素:*(指针变量+0) *指针变量指针变量[0];

    (2). 引用下标为 i 的数组元素:*(指针变量+i) 等同于 指针变量[i] 或者 指针变量[i] 等同于 数组名[i];

    4. 当指针变量指向一维数组元素,利用指针变量引用数组元素的方法如下:

    (1). 引用下标为 i 的数组元素:*(指针变量 + 0)*指针变量;

    (2). 引用下标为 i-k 的数组元素:*(指针变量 - k);

    (3). 引用下标为 i+k 的数组元素:*(指针变量 + k);

    上面的总结文字看起来有枯燥,下面两张图看起来会更生动和形象一些。

     还有下面这张:

    9. 指针和字符串

    将指针变量指向字符串的方法如下:

    1. 在数据定义语句中用赋初值的方式:*指针变量=字符串;

    2. 在程序中用赋值的方式:指针变量=字符串;

    需要注意的是,这两种方法并不是将字符串赋予指针变量,而是将存放字符串的连续内存单元的首地址赋予指针变量。

    当指针变量指向字符串时,则可以利用指针变量处理字符串,处理方式有以下几种:

    1. 处理整个字符串

    (1). 输出整个字符串:printf("%s",指针变量);

    (2). 输入整个字符串:scanf("%s",指针变量);

    #include "stdio.h"
    int main(){
      char *string = "I love China";
      printf("%s",string);
      // I love China
      return 0;
    }
    

    2. 处理字符串中的单个字符

    (1). 输出整个字符串:printf("%c",指针变量);

    (2). 输入整个字符串:scanf("%c",指针变量);

    #include "stdio.h"
    int main(){
      char *string = "I love China";
      for(;*string!='\0';string++){
        printf("%c",*string);
        // I love China
      };
      return 0;
    }
    

    C语言中,字符串是按字符数组进行处理的,系统存储一个字符串时先分配一个起始地址,从该地址开始连续存放字符串中的字符,这一起始地址即字符串首字符的地址。所以,可以将一个字符串赋值给一个字符数组,也可以赋值给一个字符指针变量。

    常见的字符串的表现形式如下:

    1. 用字符数组表示字符串

    2. 用字符指针表示字符串

    3. 用下标存取字符串中的字符

    字符指针和字符数组的区别:

    1. 存储内容不同;

    2. 赋值方式不同;

    3. 字符指针变量在定义后应先赋值才能引用;

    4. 指针变量的值是可以改变的,字符指针变量也不例外;而数组名代表数组的首地址,是一个常量,而常量是不能改变的。

    10. 指针和函数

    指针变量既可以作为函数的形参,也可以作为函数的实参。指针变量作为函数参数,形参和实参之间的数据传递方式本质上是值传递,只是在调用函数时传递的内容是地址,这样使得形参变量和实参变量指向同一个变量。若被调函数中有对形参所指变量内存的改变,实际上是改变了实参所指变量的内容。

    数组名作为函数形参时,接收实参数组的首地址;数组名作为函数实参时,将数组的首地址传递给形参数组。

    引入指向数组的指针变量后,数组及指向数组的指针变量作为函数参数时,可有四种等价形式:

    1. 形参、实参均为数组名;

     2. 形参、实参均为指针变量;

    3. 形参为指针变量、实参为数组名;

     4. 形参为数组名、实参为指针变量

    C语言中,函数可以返回整型、实型、字符型数据,也可以返回指针类型数据,即返回一个地址。指针型函数是指函数的返回值是指针型,即这类函数的返回值必须是地址值,调用该类函数时,接收返回值的必须是指针变量、指针数组元素等能够存放地址值的对象。

    定义指针型函数的格式和有返回值的函数的定义格式基本相同,唯一的区别是在函数名前面加一个“*”,表示函数的返回值是指针型数据。

    指针型函数的调用和一般函数的调用方法完全相同,但需要注意的是只能使用指针变量或指针数组元素接收指针型函数的返回值,不能使用数组名接收指针型函数的返回值,因为函数名是地址常量,不是地址型变量,不能接收地址型变量数据。

    11. 指针数组

    指针数组是数组中的元素均为指针变量。

    格式:数据类型符 *指针数组名[数组长度]。

    功能:定义指针数组,有“长度”个数组元素。

    定义说明:

    1. 指针数组名是标识符,前面必须加“*”号;

    2. 定义指针数组的同时可以定义普通变量、数组和指针变量等;

    3. “数据类型符” 可以是任何基本数据类型,“数据类型符”不是指针数组元素中存放的数据类型,而是其所指向数据的数据类型。

    指针数组的初始化

    1. char *ps[]={"China","America","Russia",NULL};

    定义了一个用于指向字符型数据的指针数组ps,其长度为4,同时对指针数组元素赋初值,前面三个是字符型指针,最后一个是空指针。

    2. int a[3][3]={1,2,3,4,5,6,7,8,9}; int *p[3]={a[0],a[1],a[2]};

    利用二维数组元素初始化指针数组p,其长度为3,分别指向二维数组a中的三个一维数组的首地址。

    指针数组元素的赋值

    1. 将数组名赋予指针数组各元素

    char s[4][20]={“China”,”America”,”Russia”,NULL}; char *p[4]; p[0]=s[0];

    给指针数组元素p[0]赋值s[0],s[0]是字符串“China”的首地址。

    2. 将字符串直接赋予指针数组元素

    char *p[4]; p[0]=“China”;

    直接给指针数组元素p[0]赋值为字符串“China”的首地址。

    指针元素的使用

    指针数元素的使用和指针变量的使用完全相同,可以对其赋予地址值,可以利用其引用所指向的变量或数组元素,也可以参与运算。

     指针元素应用实例

    1. 指针在整形二维数组中的使用

     2. 定义三个国家的名称,将国家名称按字母顺序排序后输出。

    展开全文
  • C语言中指针变量详解

    2021-05-22 08:29:25
    CPU 访问内存时需要的是地址,而不是变量名和函数名!...#include //指针变量测试//指针变量存储的值是另一个变量的地址,也就是说改指针变量指向了另一个变量int main(){int a=10;int c=20;//1.打印出变量的内存地址...
  • C语言指针的功能强大,使用灵活多变,可以有效地表示复杂的数据结构、动态分配内存、高效地使用数组和字符串、使得调用函数时得到多个返回值。而它的应用远不限于此。初学者对于指针的概念总是感到无所适从,有时...
  • 大家好,我是小风哥。 假定给你一块非常小的内存,这块内存只有8字节,这里也...这时如果你想计算1+2,那么你必须先把1和2分别放到两个小盒子,假设我们使用Store指令,把数字1放到第6号小盒子,那么用指令表示就是
  • C语言指针基本概念与理解 欢迎关注AWP资讯 指针是C/C++编程语言的重要概念,但是对于初级程序员来说,指针是个比较难理解的概念,下面就从指针的概念入手,一点点解密指针。学习并理解指针首先已经具备基本的编程...
  • 首先来分别看一下,指针数组的一个小例子:#include #include int lookup_keyword(const char*key, const char* table[], const int size){int ret = -1;int i = 0;for(i=0; i{if (strcmp(key, table[i]) == 0){ret ...
  • C语言中指针常见问题

    2021-05-20 02:10:58
    1.什么是指针指针的类型和指针指向的类型的区别?什么是指针的值?指针是变量,系统为指针分配内存空间,指针内部存的值是特殊值–地址。指针的类型意思是 这个指针是什么数据类型的指针指针指向的类型是访问所...
  • C语言中指针指针简单理解。做下笔记,记录下学的成果。定义如果一个指针变量存放的又是另一个指针变量的地址,则称这个变量为指向指针指针变量或指向指针指针。如下图所示:其中a为int的变量,值为99。指针...
  • 深入理解C语言指针指针是C语言广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构;能很方便地使用数组和字符串; 并能象汇编语言一样处理内存地址,从而编出...
  • 1、指针也是一种变量,占用空间内存,用来保存内存地址。所以无论指向何种数据类型的指针,编译器都给指针类型分配固定的内存空间如果说是32位那就都分配4个字节,如果是64位那就都分配8个字节。//32位计算机typedef...
  • C语言指针,便于理解

    千次阅读 2021-05-25 06:40:01
    一、指针变量定义C语言有两种变量:其中变量(普通变量)存储内容值;地址变量(指针变量)存储地址值。1、定义的格式:类型名 *指针变量名;如:int a,b,*p1,*p2;float x,y,*p3,*p4;chars,*p5,*p6;注:(1)...
  • 摘要:在C语言中指针是教学最大的难点,在学习初,尤其对数组和指针的相关语法感到非常“纠结”,常常一头雾水。那么,指针和数组到底有什么关系呢?在我们还不了解的时候,我们不防先这样告诉自己:“它们之间...
  • C语言中指针和数组是否相等?简短的答案:不相等。详细的答案:这依赖于如何定义“相等”。指针运算和数组下标是相等的,其他方面指针和数组是不同的。一个简单的例子展示相等性:#include int main(){char arr[] = ...
  • 指针对于我们搞嵌入式开发的菜鸟来说非常的重要,因为太...当编译器看到这句话时,认为p包含了一个char类型变量的地址,这是我们菜鸟对指针通常的理解。恭喜,理解的没错!但还太肤浅哦,我们一起深入进去吧!2、指...
  • c语言指针用法详解,通俗易懂超详细!

    千次阅读 多人点赞 2021-07-18 00:10:30
    文章转自:无际单片机大家好,我是无际。今天给大家来讲解一下指针。我会由浅到深,最后结合实际应用讲解,让大家学会指针的同时,知道大佬们都用指针来干嘛!长文预警!全文大约5200多字,学指针看...
  • C语言指针深入理解

    2021-05-24 02:54:50
    前几天看了一个程序,里面一段关于指针的代码让我非常纠结,看了很久才看懂,在这里将将其记录下来,希望能对大家有一定的帮助,先看示例程序(编译器gcc):#include #include #include typedef struct list_node{int...
  • C语言中指针解读

    2021-05-21 10:49:54
    C语言中指针解读指针无疑是一个难点。但是,我觉得指针也是C语言特别重要的一个特性。也许,你在除了C和C++以外的编程语言,很少看到指针。而C++,也多用引用,而非指针指针,作为一种高效的工具,可谓是一...
  • C语言函数指针的用法

    2021-05-21 08:54:01
    这篇文章简单的叙述一下函数指针在结构体的应用,为后面的一系列文章打下基础引言指针C语言的重要组成部分, 于是深入理解指针并且高效地使用指针可以使程序员写出更加老练的程序。我们要记住指针是一个指向内存...
  • C语言中指针浅谈

    2021-05-19 02:47:07
    C语言中,较难理解的就是指针。本文试图通过论述指针的定义、分类、运算以及3特殊的用途,让大家能较清晰的认识指针的本质。可以预见的是只有深入的掌握的了指针才能真正的掌握了C语言。通过深入的应用指针,C语言...
  • 如何理解C语言指针

    2021-05-26 08:41:21
    如何理解C语言指针[Explain]#define PF "%d,%d,%d,%d,%d,\n"main(){static int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};printf(PF,a,*a,a[0],&a[0],&a[0][0]);printf(PF,a+1,*(a+1),a[1],&a[1],&a[1]...
  • C语言指针面试题“指针可以访问内存,函数传递形参时加个*号可以改变内容”,这基本就是很多初学者对指针的全部理解。但是一用起来就到处出错,总是“云里雾里”,今天专门地说说指针的那些事。1、指针的“两...
  • 刚学习C语言的朋友,对指针“移动”可能不太理解。举个例子,例如下述代码:int a = 1;那么大家都知道a + 1肯定就是2了。如果是指针呢?例如:int *p = 1;p + 1还是2吗?为了说明问题,请看以下代码:#include ...
  • C语言中指针的用法

    2021-05-21 10:31:13
    #includevoidmain(void){inta[5]...}代码的输出是: 2, 5这是C语言里一个比较容易搞混的地方,很多人直接把数组名当成数组第一个元素的地址,其实两者间有一点差异的。大多情况下,数组名确实可以当做数组第一个元素...
  • 聊聊c语言中指针

    2021-05-21 16:49:28
    *p 意思就是这个地址存放的内容。3.野指针和NULL什么是野指针呢?野指针指向一个已删除的对象或未申请访问受限内存区域的指针。什么是空指针呢?就是你定义了一个指针却没有指向任何地址。例程(为...
  • 1、const 的理解const 是C语言(C )的一个关键字,需要注意的是,const 关键字是把变量变为一个只读的变量,绝对不是将这个变量变为常量。也就是说经过const 修饰的变量成为只读的变量之后,那么这个变量就只能作为...
  • C语言数组指针_3

    2021-05-21 09:38:45
    C语言中的数组指针指针数组:·数组指针一、区分首先我们需要了解什么是数组指针以及什么是指针数组,如下:int *p[5];int (*p)[5];数组指针的意思即为通过指针引用数组,p先和*结合,说明了p是一个指针变量,指向...
  • c语言指针基础知识

    2021-05-18 12:33:41
    c语言指针基础知识将指针和普通变量进行比较,将有助于您理解指针。所谓“普通变量”就是存储器能够保存数值的一个位置。例如,当您声明变量i为一个整数时,四个字节的存储空间就为它预留出来了。程序中用i表示...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 132,731
精华内容 53,092
关键字:

c语言中指针的理解

c语言 订阅