C语言学习——指针精华(2)

C语言学习——指针精华(2)字符指针作函数参数[用函数调用实现字符串的复制]⑴用字符数组作参数#include <stdio.h>void copy_string(char from[], char to[]);int main(){ char a[] = “I am a teacher.”; char b[] = “You are a student.”; printf(“strin…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

在这里插入图片描述
在这里插入图片描述

字符指针作函数参数

[用函数调用实现字符串的复制]
⑴用字符数组作参数

#include <stdio.h>
void copy_string(char  from[], char to[]);

int main()
{ 
   	
	char a[] = "I am a teacher.";
	char b[] = "You are a student.";
	printf("string_a=%s\n string_b=%s\n", a, b);
	printf("copy string_a to string_b : \n");
		copy_string(a, b);   /* 数组名作参数是地址传递*/
	printf("\nstring_a = %s\nstring_b = %s\n",a,b);
	
	return 0;
}
void copy_string(char  from[], char to[])
{ 
   
	int i = 0;
	while (from[i] != '
#include <stdio.h>
void copy_string(char  from[], char to[]);
int main()
{ 
	
char a[] = "I am a teacher.";
char b[] = "You are a student.";
printf("string_a=%s\n string_b=%s\n", a, b);
printf("copy string_a to string_b : \n");
copy_string(a, b);   /* 数组名作参数是地址传递*/
printf("\nstring_a = %s\nstring_b = %s\n",a,b);
return 0;
}
void copy_string(char  from[], char to[])
{ 

int i = 0;
while (from[i] != '\0')
{ 

to[i] = from[i];  i++;
}
to[i] = '\0';
}
'
) { to[i] = from[i]; i++; } to[i] = '
#include <stdio.h>
void copy_string(char  from[], char to[]);
int main()
{ 
	
char a[] = "I am a teacher.";
char b[] = "You are a student.";
printf("string_a=%s\n string_b=%s\n", a, b);
printf("copy string_a to string_b : \n");
copy_string(a, b);   /* 数组名作参数是地址传递*/
printf("\nstring_a = %s\nstring_b = %s\n",a,b);
return 0;
}
void copy_string(char  from[], char to[])
{ 

int i = 0;
while (from[i] != '\0')
{ 

to[i] = from[i];  i++;
}
to[i] = '\0';
}
'
; }

结果:
在这里插入图片描述
【字符指针变量作形参】

#include <stdio.h>

void FuncPArs(char *s)
 { 
   
	printf("Result:%s\n", s);
}

int main()
{ 
   
	char rsa[] = "Welcome To C/C++.\n";
	FuncPArs(rsa);

	return 0;
}

结果:
在这里插入图片描述

对使用字符指针变量和字符数组的讨论

char *cp; 与 char str[20]; 的区别
str由若干元素组成,每个元素放一个字符;而cp中存放字符串首地址
赋值方式:
字符数组只能对元素赋值。 char str[20];
str=“I love China!”; ()
字符指针变量可以用: char *cp;
cp=“I love China!”; ()
赋初值:char *cp=“China!”; 等价 char *cp; cp=“China!”;
char str[14]={“China”};不等价char str[14]; str[ ]=“China” ()

【用下标法引用指针变量所指的字符串中的字符】

#include <stdio.h>

int main()
{ 
   
	char *a = "I love China!"; int i;
	printf("The sixth charcter is %c\n", a[5]);
	for (i = 0; a[i] != '
#include <stdio.h>
int main()
{ 

char *a = "I love China!"; int i;
printf("The sixth charcter is %c\n", a[5]);
for (i = 0; a[i] != '\0'; i++)
printf("%c", a[i]);
printf("\n");
return 0;
}
'
; i++) printf("%c", a[i]); printf("\n"); return 0; }

结果如下:
在这里插入图片描述
在这里插入图片描述
用指针变量指向的格式字符串代替printf中的格式字符串(可变格式输出函数)char *format; format="a=%d,b=%f\n"; printf(format,a,b);相对于:` printf(“a=%d,b=%f\n”a,b);
可以用字符数组实现:

   char format[ ]="a=%d,b=%f\n";
   printf(format,a,b);

在这里插入图片描述

二、函数指针与指针函数

函数指针的实质(还是指针变量)
函数指针定义格式

类型名 (*函数名)(函数参数列表);
int (*pfun)(int, int);

函数指针的定义_赋值_调用
void FuncTest(void) //定义一个函数,以方便下面定义函数指针
{

printf(“FunPointer DemoTestFunc.\n”);
}

【案例如下】

void (*pFunc)(void);// 函数指针定义
pFunc = FuncTest;   // 函数指针赋值
(*pFunc)();         // 函数指针调用;用函数指针来调用以调用该函数,注意*pFunc要用()括起来
pFunc();            // 调用的第二种写法,效果和上面一样

函数指针作用:函数指针有两个用途:调用函数和做函数的参数。

注意:函数指针声明为指针,它与变量指针不同之处是,它不是指向变量,而是指向函数。

(1)函数指针的实质还是指针,还是指针变量。本身占4字节;

(2)函数指针、数组指针、普通指针之间并没有本质区别,区别在于指针指向的内容是什么;

(3)函数的实质是一段代码,这一段代码在内存中是连续分布的(一个函数的大括号括起来的所有语句将来编译出来生成的可执行程序是连续的),所以对于函数来说很关键的就是函数中的第一句代码的地址,这个地址就是所谓的函数地址,在C语言中用函数名这个符号来表示;

(4)结合函数的实质,函数指针其实就是一个普通变量,这个普通变量的类型是函数指针变量类型,它的值就是某个函数的地址(也就是它的函数名这个符号在编译器中对应的地址值)。

指针函数实质是一个函数
指针函数实质是一个函数。函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。

*指针函数定义格式:类型名 函数名(函数参数列表);
int *pfun(int, int);

指针函数的声明_定义_调用

int * sum(int x);   		//指针函数的声明;返回类型位一个指针变量 可以通过*p来获取值

int * sum(int x) 			//指针函数的定义
{ 
          
	int static sum = 0;   	//static 修身的变量在数据段;不会被函数栈回收
	int *p;
	int i;
	for (i = 1; i <= x; i++)
	{ 
   
		sum += i;  // sum=sum+i;
		return p;     	//返回类型是某一类型的指针
	}
}

int *p1;
p1 = fun(a);      			//指针函数的调用

指针函数作用:可以使代码更简洁并在一定程度节约内存;如当你需要返回一个数组中的元素时,你就只需返回首元素的地址给调用函数,调用函数即可操作该数组(让函数返回多个值)。

或者是malloc函数动态分配内存,返回该内存的地址给另外一个函数,另一个函数才好操作该内存。当然还有其他的作用,请读者自行在实践中体会。

注意:指针函数本质是一个函数,使用方法与普通函数没什么两样。既然是函数,就与变量不一样。变量需要定义、赋值、调用(比如函数指针);而函数需要声明、定义、调用。

【工程案例】
输入第几周的第几天获取这天是这个月的几号


#include<stdio.h>
int * GetDate(int wk, int dy);	// 声明指针函数
int main()
{ 
   	
        int wk, dy;	
        do 
        { 
   
                 printf("Enter week(1 - 5)day(1 - 7)\n");
	   scanf_s("%d%d", &wk, &dy);
        } while (wk < 1 || wk>5 || dy < 1 || dy>7);
        printf("%d\n", *GetDate(wk, dy));	
	// 调用,GetDate()函数返回的是一个指针(地址)
	// * GetDate()则是取其内容
        return 0;
}
int * GetDate(int wk, int dy)
{ 
   
         static int calendar[5][7] = { 
    
	{ 
    1, 2, 3, 4, 5, 6, 7 },
	{ 
    8, 9, 10, 11, 12, 13, 14 },
	{ 
    15, 16, 17, 18, 19, 20, 21 },
	{ 
    22, 23, 24, 25, 26, 27, 28 },
	{ 
    29, 30, 31, -1 } };
        //返回一个地址
        return &calendar[wk - 1][dy - 1]; 
}

结果如下:
在这里插入图片描述

## 三、数组指针与指针数组

【工程案例】

#include <stdio.h>

int main()
{ 
   
	int x = 89;
	int y = 92;

	int *p[2];	// 指针数组 元素里面全部都是指针
	printf("x的地址:%p , y的地址:%p\n",&x,&y);

	p[0] = &x;	p[1] = &y;
	printf("p[0]的值:%p , p[1]的值:%p\n", p[0],p[1]);
	printf("\n输出指针数组所指向地址里面的值:\np[0]的值:%d , p[1]的值:%d\n", *p[0], *p[1]);
	return 0;
}

在这里插入图片描述

在这里插入图片描述
【工程案例】

#include <stdio.h>

// 函数申明
void mymemset(void *data, int num, int byteSize);

int main()
{ 
   	
	int nums[20];
	mymemset(nums, 0, sizeof(nums));
	int i, len = sizeof(nums) / sizeof(int);
	for (i = 0; i<len; i++) 
	{ 
   
		printf("%d ", nums[i]);
	}
	printf("\n");
	return 0;
}
void mymemset(void *data, int num, int byteSize)
{ 
   	
// char就是一个字节,而计算机中是以字节为单位存储的
	char *ptr = (char*)data;
	int i;
	for (i = 0; i<byteSize; i++) 
	{ 
   
		*ptr = num;
		ptr++;
	}
}

结果如下:
在这里插入图片描述
在这里插入图片描述
一、函数参数传递方式之一(值传递)

#include <stdio.h>
void ExceFun(int x, int y)
{ 
   
	int temp;
	temp = x;
	x = y;
	y = temp;
	printf("x=%d, y=%d\n", x, y);
}
int main()
{ 
   
	int a = 89, b = 65;
	ExceFun(a, b);
	printf("a=%d, b=%d\n", a, b);
	return 0;
}

二、函数参数传递方式之二(地址传递)

#include <stdio.h> 
void ExceFun(int *px,int *py)
{ 
   
	int temp;
	temp=*px;
	*px=*py;
	*py=temp;
	printf("*px=%d, *py=%d\n", *px,*py);
}
int main( )
{ 
   
	int a=89, b=65;
	ExceFun(&a,&b);
	printf("a=%d, b=%d\n",a,b);
	return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/170989.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Stimulsoft 仪表板.JS 2022.2.1

    Stimulsoft 仪表板.JS 2022.2.1Stimulsoft仪表板.JS2022.2.1  二维码视觉设计-使用组件编辑器中的属性定义各种图形元素的颜色和形状。  仪表板的新交互式按钮组件-允许您使用脚本平台语言或Blockly执行脚本。它包括几个可视化设置,这些设置取决于按钮的状态。  仪表板的新卡片组件-此分析组件允许您将数据分组、处理和显示为仪表板中的卡片。它支持所有类型的图形表示,包括集群列、色标、指标、气泡和迷你图。它能够显示文本、数值和图像。  仪表板的新图形堆叠图表类型-此图表用于显示值在整体指标中的

  • int与bigdecimal的相互转换[通俗易懂]

    int与bigdecimal的相互转换[通俗易懂] int转bigdecimalBigDecimalnumber=newBigDecimal(0);intvalue=score;number=BigDecimal.valueOf((int)value);bigdecimal转intBigDecimalb=newBigDecimal(45.45);inta=b.intValue(); …

  • BT渗透「建议收藏」

    BT渗透「建议收藏」PHP交流群:294088839,Python交流群:652376983 whois域名/ip查看域名的详细信息。ping域名/ip测试本机到远端主机是否联通。dig域名/ip查看域名解析的详细信息。host-l域名dns服务器传输zone。扫描nmap:-sS半开扫描TCP和SYN扫描。-sT完全TCP连接扫描。-sUUDP扫描-PSs…

  • 带有机器人框架的.NET自己主动化測试

    带有机器人框架的.NET自己主动化測试

  • kettle基础教程-kettle9教程「建议收藏」

    kettle基础教程-kettle9教程「建议收藏」一.安装部署1.JDK1.8安装及环境变量的配置https://blog.csdn.net/weixin_39549656/article/details/795406442.kettle9安装与启动kettle下载目录:https://sourceforge.net/projects/pentaho/files/kettle9.2下载地址:https://sourceforge.net/projects/pentaho/files/Pentaho-9.2/client-tool

  • oracle数据库904_oracle00933怎么解决

    oracle数据库904_oracle00933怎么解决今天早上在日志中发现exp备份时出错:..exportingtableBJ_AFFILIATES37rowsexportedEXP-00008:ORACLEerror904encounteredORA-00904::invalididentifier..exportingtable…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号