首页 > 其他分享 >C语言学习入门 (五) 指针

C语言学习入门 (五) 指针

时间:2022-12-09 21:38:15浏览次数:47  
标签:入门 指向 int C语言 char printf 变量 指针


直接引用

char a;

a = 10;

程序内部是怎么操作的呢?

其实,程序对变量的读写操作,实际上是对变量所在的存储空间进行写入或取出数据。就上面的代码而言,

系统会自动将变量名a转换为变量的存储地址,根据地址找到变量a的存储空间,然后再将数据10以2进制的形式放入变量a的存储空间中。 

 通过变量名引用变量,由系统自动完成变量名和其存储地址之间的转换,称为变量的"直接引用"方式


间接引用

如 将变量a的地址存放在另一个变量中,比如存放在变量b中,然后通过变量b来间接引用变量a,间接读写变量a的值。这就是"间接引用"

总结一句:用来存放变量地址的变量,就称为"指针变量"。在上面的情况下,变量b就是个"指针变量",我们可以说指针变量b指向变量a。

指针的定义

一般形式:类名标识符  *指针变量名;

int *p;

float *q;

  • "*"是一个说明符,用来说明这个变量是个指针变量,是不能省略的,但它不属于变量名的一部分
  • 前面的类型标识符表示指针变量所指向的变量的类型,而且只能指向这种类型的变量

指针的初始化

int a = 10;int *p = &a;      float b = 2.3f;   float *q; q = &b;

指针运算符

给指针指向的变量赋值

char a = 10;

printf("修改前,a的值:%d\n", a);


// 指针变量p指向变量a

char *p = &a;//这个*  是定义指针的说明符


// 通过指针变量p间接修改变量a的值

*p = 9;//这个* 是指针运算符,表示 把9赋值给  指针指向的地址a,也就相当于 a = 9;

//这里 就是间接修改a的值

printf("修改后,a的值:%d", a);

取出指针所指向变量的值

char a = 10;

 

char *p;

p = &a;


char value = *p;//根据p值(即变量a的地址)访问对应的存储空间,并取出存储的内容(即取出变量a的值),赋值给value

printf("取出a的值:%d", value);

使用注意

在指针变量没有指向确定地址之前,不要对它所指的内容赋值。下面的写法是错误的




int *p; 

*p = 10; //这是错误的

应该在指针变量指向一个确定的变量后再进行赋值。下面的写法才是正确的

// 定义2个int型变量

int a = 6, b;


// 定义一个指向变量b的指针变量p

int *p;

p = &b;


// 将a的值赋值给变量b

*p = a;

例子

 交换两个字符变量的地址(改变实参的值)

void swap(char *p,char

{

char

    *p = *q;

    *q = temp;

    

}


int main(int argc,constchar

{

char a ='A', b ='&';

swap(&a, &b);

printf("a=%c b=%c\n”, a, b);

}

用指针指向一维数组的元素

int a[2] = {2, 3};   int *p = &a[0];  *p = 10;  那么 a[0]应该等于10

数组名a 的地址 与 它的第一个元素的地址相同,  所以  p = &a[0] 与 p = a 效果一样 

指针来遍历数组元素

int ary[] = {1,2,3,4, 5};

int

for (int i =0; i <5; i++)

    {

        //数组内元素内存地址是连续的存储方式,指针移动一个对应类型单位字节数(int、char...),则指向下一个元素值

//        printf("数为:%d ", *(q+i)); //地址移动

//        printf("数为:%d ", *(ary+i)); //地址移动

printf("数为:%d ", *(q++));//q=q+1,指针指向的地址移动

//        printf("数为:%d ", *(ary++)); //错误,常量不能赋值

    }




数组、指针、函数参数

形参数组,实参指针

void change(int b[]) {

    b[0] = 10;

}


int main()

{

    // 定义一个int类型的数组

    int a[4] = {1, 2, 3, 4};

    

    int *p = a;


    // 将数组名a传入change函数中

    change(p);

    

    // 查看a[0]

    printf("a[0]=%d", a[0]);

    

    return 0;

}

形参指针,实参数组

void change(int *b) {

b[0] = 10;

    // 或者*b = 10;

    b[1] = 11;

   // 或 *(b+1) = 11;

}


int main()

{

    // 定义一个int类型的数组

    int a[4] = {1, 2, 3, 4};


    // 将数组名a传入change函数中

    change(a);

    

    // 查看a[0]

    printf("a[0]=%d", a[0]);

    

    return 0;

}   //可以看出,在很多情况下,指针和数组是可以相互切换使用的。但是,并不能说指针就等于数组





用指针遍历字符串的所有字符

char chs[] ="abcde";

char

    p = chs;

for (; *p != '\0';p++)

    {

printf("data:%c ", *p);

    }

printf("\n");





用指针直接指向字符串

char *p ="abcde";   

strlen("abde”);

函数在string.h中的声明

size_t     strlen(const char

char    *strcpy(char *,const char *);// 字符串拷贝函数

char    *strcat(char *,const char *);// 字符串拼接函数

int     strcmp(constchar *, constchar *); // 字符串比较函数

它们的参数都是指向字符变量的指针类型,因此可以传入指针变量或者数组名。

指针指向字符串的其他方式

1 char s[10];

2 s ="mj"; //编译器肯定报第2行的错,因为s是个常量,代表数组的首地址,不能进行赋值运算


1 char *s ="mj";

2

3 *s = "like";

第3行代码犯了2个错误:

  • 第3行代码相当于把字符串"like"存进s指向的那一块内存空间,由第1行代码可以看出,s指向的是"mj"的首字符'm',
  • 也就是说s指向的一块char类型的存储空间,只有1个字节,要"like"存进1个字节的空间内,肯定内存溢出
  • 由第1行代码可以看出,指针s指向的是字符串常量"mj"!因此是不能再通过指针来修改字符串内容的!
  • 就算是*s = 'A'这样"看起来似乎正确"的写法也是错误的,因为s指向的一个常量字符串,不允许修改它内部的字符。


  • char a[] ="lmj";定义的是一个字符串变量! char *p = a;  *p = ‘L’;  变量可以通过指针改变,常量不行
  • char *p2 = "lmj";定义的是一个字符串常量!




返回指针的函数

返回指针的函数的一般形式为:类型名 *函数名(参数列表)

// 将字符串str中的小写字母变成大写字母,并返回改变后的字符串

// 注意的是:这里的参数要传字符串变量,不能传字符串常量



[plain] ​​view plain​​​​copy​​​​pr



  1. char * upper(char *str) {  
  2.     // 先保留最初的地址。因为等会str指向的位置会变来变去的。  
  3.     char *dest = str;  
  4.     // 如果还不是空字符  
  5.     while (*str != '\0') {  
  6.         // 如果是小写字母  
  7.         if (*str >= 'a' && *str <= 'z') {  
  8.             // 变为大写字母。小写和大写字母的ASCII值有个固定的差值  
  9.             *str -= 'a' - 'A';  
  10.         }  
  11.         // 遍历下一个字符  
  12.         str++;  
  13.     }  
  14.     // 返回字符串  
  15.     return dest;  
  16. }  
  17.   
  18. int main()  
  19. {  
  20.     //定义一个字符串变量  
  21.     char str[] = "lmj";  
  22.     // 调用函数  
  23.     char *dest = upper(str);  
  24.       
  25.     printf("%s", dest);  
  26.     printf("%s", str);  
  27.     return 0;  
  28. }  



指向函数的指针

定义的一般形式:函数的返回值类型 (*指针变量名)(形式参数1,形式参数2, ...);

注意:形式参数的变量名可以省略,甚至整个形式参数列表都可以省略

int sum(int a,int

{

return

}

int main()

{

int (*q) (int a,int b) = sum;// (int a, int b) 可以写成(int a, int)或(int,int)或()

int result = (*q)(2,5);//调用函数

printf("\n%d", result)

return 0;

}

将函数作为参数

void get(int (*q)(int a,char b), float

标签:入门,指向,int,C语言,char,printf,变量,指针
From: https://blog.51cto.com/u_11407799/5926567

相关文章

  • 【C语言】03-关键字、标识符、注释
    一、关键字1.什么是关键字C语言提供的有特殊含义的符号,有些地方也叫做“保留字”。 2.一共有哪些关键字C语言一共提供了32个关键字,这些关键字都被C语言赋予了特殊含义......
  • Atlas快速入门之实战Atlas
    随着ajax技术的出现,web2.0时代已经来临,目前已经涌现了大量的web2.0的网站,比如live.com,fclickr相册网站,​​google​​Map等等。那什么是ajax呢?AJAX技术其实是旧瓶装新酒......
  • 会话技术_概述以及Cookie快速入门
    会话技术_概述会话:一次会话中包含多次请求和响应一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止功能:在一次会话的范围内的多次请求间,共享数......
  • 01-JavaSE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行
    01-JavaSE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行Java的发展历史Java是一种面向对象的程序设计语言,由SunMicrosystems公司的JamesGosling等人于......
  • ffmpeg库安装及入门指南(Windows篇)- 2022年底钜献
    最近项目需要,使用了ffmpeg做摄像头视频采集和串流。这几天有点时间,打算把相关的一些知识记录分享一下。在撰写本文时,我又在另外一台电脑上把ffmpeg重新安装了一遍,所以......
  • C语言-第三天!
    关键字(32个)关键字说明​​auto​​声明自动变量​​short​​声明短整数​​int​​声明整数​​long​​声明长整数​​float​​声明单精度浮点型​​double​​声明双......
  • C语言运算符优先级列表
    初级运算符()、[]、->、.  高于  单目运算符高于算数运算符(先乘除后加减)高于关系运算符高于逻辑运算符(不包括!)高于条件运算符高于赋值运算符高于逗号......
  • C语言中的结构体与C++中的类异同
    从C语言到C++,是编程思想的进步,技术发展的结果吧,所以C++基本上是兼容C的语法的,C++的很多东西也是从C中继承过来的,然后再发扬,C语言的结构体便是C++中类的雏形。       ......
  • OC之【指向指针的指针】
    #import<Foundation/Foundation.h>voidchangeC(char9;}voidchangeStr(NSString@"123";}intmain(intargc,constchar{@autoreleasepool{//charc=......
  • OC之【c语言结构体】
    <stdio.h>void//这个机构只能在函数内部使用//定义一个名为Student的结构体类型structintage;//年龄char*name;//姓名floatheight;//身高};......