首页 > 其他分享 >C语言之指针(中)

C语言之指针(中)

时间:2023-11-11 12:31:59浏览次数:31  
标签:变量 int double C语言 字符串 动态 指针

动态内存分配

动态变量

所谓的动态变量是指:在写程序时无法确定它们的存在,只有当程序运行起来,随着程序的运行,根据程序的需求动态产生和消亡的变量。因此,动态变量的访问需要通过指向动态变量的指针变量来进行间接访问。当程序运行结束时,系统会自动回收指针占用的空间,但并不会回收指针指向的动态变量的空间,动态变量的空间需要程序员在程序中释放。因此,要实现动态内存分配,程序设计语言必须提供3个功能:

  • 定义指针变量。
  • 申请动态变量的空间。
  • 回收动态变量的空间。

动态变量的创建

1.malloc函数

malloc创建一个动态变量。

语法:

void *malloc(unsigned int size);

其作用是在内存称为堆(heap)的区域申请一块长度为size的空间,函数的返回值是这块空间的首地址。如果函数没有成功地申请到空间,则返回值为空指针NULL。

如:

int *p1;
p1=(int *)malloc(sizeof(int));
double *p2;
p2=(double *)malloc(sizeof(double));
//一旦申请成功,就可以通过间接地方式访问动态变量。
*p1=5;
*p2=*p1+0.5;
2.calloc函数

calloc用于创建一个动态数组。

语法:

void *calloc(unsigned n,unsigned size);

其作用是申请n个长度为size的连续空间,即申请n个元素的数组,每个数组元素均占用size个字节。函数返回这块连续空间的起始地址。如果申请失败,返回空指针NULL。如:

int *array;
array=(int *)calloc(10,sizeof(int));  //此时,array指向这块空间的首地址,相当于一个数组名,可以通过下标变量形式访问该动态数组。

动态数组和普通数组的最大区别在于,它的规模可以是程序运行过程中某一变量的值或某一表达式的计算结果,而普通数组的长度必须是在编译时就能确定的常量。

动态变量的消亡

一旦申请了动态变量,如果不明确给出指令是不会消亡的。要回收动态变量的空间,就必须显示地使之消亡。

回收某个动态变量,可以调用函数free。语法如下:

// void free(void *p);
double *p=(double *)malloc(sizeof(double));
free (p);

一旦释放了内存区域,堆管理器将重新收回这些区域。如果再间接访问这块空间,将导致程序异常终止。

内存泄漏

所谓的内存泄漏是指用动态变量机制申请了一个动态变量,而后不再需要这个动态变量时没有释放它;或者把一个动态变量的地址放入一个指针变量,而在此变量没有释放之前又让指针指向另一个动态变量。这样原来那块空间就丢失了。堆管理器认为程序在继续使用它们,而程序又不知道它们在哪里。为了避免出现这种情况,在动态变量不再使用时,应该用free函数明白地告诉堆管理器这些区域不再使用。

查找malloc和calloc的失误

由于计算机的空间内存是有限的,堆空间最终也可能耗尽,此时malloc和calloc就会失败,为保险起见,在调用它们之后最好检查一下操作是否成功。可根据返回值来确定。如果成功,返回申请到的堆空间的一个地址;如果不成功,则返回一个空指针。

#include<stdio.h>
int main(){
	int *p;
	p=(int *)malloc(sizeof(int));
	if(p==NULL){
		printf("allocation failure!");
		return 1;
	}
	*p=20;
	printf("%d\n",*p);
	free(p);
	return 0;
}

也可以利用assert宏直接退出程序。

#include<stdio.h>
#include<assert.h>
int main(){
	int *p,i;
	p=(int *)calloc(10,sizeof(int));
	assert(p!=0);
	for(i=0;i<10;i++)
	    p[i]=2*i;
	for(i=0;i<10;++i)
    	printf("%d\t",p[i]);
	free(p);
	return 0;
}

C语言之指针(中)_指针变量

动态变量应用

案例1:统计某次考试的平均成绩和均方差。

#include<stdio.h>
#include<math.h>
int main(){
	int *score,num,i;//score为存放成绩的数组名 
	double average=0,variance=0;//average为平均数,variance为方差 
	printf("请输入参加考试的人数:");
	scanf("%d",&num);
	score=(int *)calloc(num,sizeof(int));
	printf("请输入成绩:");
	for(i=0;i<num;++i)
		scanf("%d",&score[i]);
	for(i=0;i<num;++i)
		average+=score[i];
	average/=num;
	for(i=0;i<num;++i)
		variance+=(average-score[i])*(average-score[i]);
	variance=sqrt(variance)/num;
	free(score);
	printf("平均分:%f\n方差:%f\n",average,variance);
	return 0;
}

C语言之指针(中)_#include_02

案例2:计算两个n维向量的数量积。

#include<stdio.h>
int main(){
	int i,scale;
	double result=0,*v1,*v2;
	printf("请输入向量的维数:");
	scanf("%d",&scale);
	v1=(double *)calloc(scale,sizeof(double));
	v2=(double *)calloc(scale,sizeof(double));
	printf("请输入第一个向量的%d个分量:",scale);
	for(i=0;i<scale;++i){
		scanf("%lf",&v1[i]);
	}
	printf("请输入第二个向量的%d个分量:",scale);
	for(i=0;i<scale;++i){
		scanf("%lf",&v2[i]);
	}
	for(i=0;i<scale;++i)
	    result+=v1[i]*v2[i];
	printf("向量的数量积是:%f\n",result);
	free(v1);
	free(v2);    
	return 0;
}

C语言之指针(中)_#include_03

result=(1*3)+(2*4)=3+8=11

指针与字符串

用指向字符的指针变量表示字符串

C语言中的字符串有两种基本表示:字符数组表示和指向字符的指针表示。

字符串作为函数的参数

字符串的本质上是用一个字符数组来存储的。

当传递的是一个字符串,通常使用指向字符的指针。

字符串有一个特定的结束标志‘\0’。

传递一个字符串只需要一个参数,即指向字符串中第一个字符的指针,而不需要指出字符串的长度。

案例1:编写一个统计字符串中单词个数的函数。

#include<stdio.h>
int Number(char *s)
{
	int count=0;
	while(*s!='\0'){
		while(*s==' ')
		++s;
		if(*s!='\0'){
			++count;
			while(*s != ' '&& *s != '\0'){
				++s;
			}
		}
	}
	return count;
}
int main(){
	char *s="This is my English teacher";
	printf("该字符串的单词个数为:%d",Number(s));
	return(0);
}

C语言之指针(中)_字符串_04

案例2:实现string库中的strcmp函数。

【解释:C 库函数 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字符串和 str2 所指向的字符串进行比较。】

#include<stdio.h>
int strcmp(char *s1,char *s2){
	while(*s1 && *s2){
		if(*s1>*s2) return 1;
		if(*s1<*s2) return -1;
		++s1;
		++s2;
	}
	if(*s1=='\0'&&*s2=='\0') return 0;
	if(*s1=='\0') return -1;else return 1;
}
int main(){
	char *s1="abc",*s2="cde";
	int cmp;
	cmp=strcmp(s1,s2);
	if(cmp){
		printf("%s%s%s\n",s1,(cmp>0)?"大于":"小于",s2); 
	}else{
		printf("%s等于%s\n",s1,s2);
	}
	cmp=strcmp(s1,s1);
	if(cmp){
		printf("%s%s%s\n",s1,(cmp>0)?"大于":"小于",s1); 
	}else{
		printf("%s等于%s\n",s1,s1);
	}
	return(0);
}

C语言之指针(中)_字符串_05

返回字符串的函数

字符串常用的表示方法是采用指向字符的指针。返回一个字符串的函数的返回值可以定义为指向字符的指针。

案例:设计一个函数从一个字符串中提取一个子串。

#include<stdio.h>
char *subString(char *s, int start,int end)
{
	int len;
	char *sub;
	for(len=0;s[len]!='\0';++len);
	if(start<0 || start >=len || end<0 || end>=len ||start >end) return NULL;
	sub=(char *)malloc(end-start+2);
	for(len=start;len<=end;++len)
	    sub[len-start]=s[len];
	sub[end-start+1]='\0';
	return sub;
}
int main(){
	char *s1="abcdefg";
	char *sub;
	sub=subString(s1,2,5);
	printf("%s的第2个字符到第5个字符是%s是\n",s1,sub);
	if(sub) free(sub);
	return(0);
}

C语言之指针(中)_字符串_06


标签:变量,int,double,C语言,字符串,动态,指针
From: https://blog.51cto.com/u_16174658/8316789

相关文章

  • C语言入门:基本语法
    如果你刚刚接触到C语言,而且感到自己写不出代码,别灰心,这是正常的学习过程。学习编程是一个渐进的过程,不要急于求成。通过不断的实践和学习,你会发现编程变得越来越容易。当你刚开始学习C语言时,最好从一个简单的"Hello,World!"程序开始,这是学习任何编程语言的传统入门方式。以下是一......
  • C语言编程 C语言入门
    1.初识C语言(1){C语言程序设计教程笔记}1基础框架/*#include<stdio.h>//格式intmain()//输入{printf("helloworld\n");//打印system("pause");//显示return0;//返回}/2注释单行//整段/...*/或Ctrl+k+c注释Ctrl+k+u解除注释//char字符类型'W'字母int数字150float小数//%......
  • 指针首汽聚合平台开启招募
    目前,我们将首汽约车代驾项目向全社会公开招募,如果您正在运营一家代驾企业、如果您有资源正在找投资项目、如果您愿意从事代驾行业,我们将与您分享首汽约车品牌价值及流量红利所带来的丰厚收益。品牌优势通过中心化品牌赋能,联合首汽约车品牌,全国范围线上线下齐推广,标准化......
  • 使用sizeof()和strlen()去计算【数组】和【指针】的大小
    (目录)一、知识回顾1、回顾sizeof()、strlen的作用:sizeof()是用来求取变量或者类型所占内存空间的大小(单位:字节)。sizeof计算的是占用内存空间的大小,单位是字节,不关注内存中到底存放的是什么。sizeof不是函数,是操作符strlen()是一个库函数是专门用来计算字符串长度的,在......
  • 利用快慢指针,求链表的中间结点,判断链表是否是环形链表
    前言(1)在学习数据结构链表部分的时候,老师给出了几个题目。其中两个题目采用了快慢指针的技术,感觉有意思,于是写一篇博客记录一下。快慢指针(1)我们先来介绍一下快慢指针技术。这个说起来其实很简单,就是龟兔赛跑问题。(2)兔子跑的比乌龟快,我们可以利用这个特性,来解决一些实际按理。求链表......
  • 看完C语言的发展历程对于Android的发展不在迷茫
    前言现在从事Android开发,前景怎么样呢?要是放在以前问起这个问题,我肯定拍胸脯的说赶紧来,狠狠赚上一笔!!!现在想想,移动互联网的发展不知不觉已经十多年了,MobileFirst也已经变成了AIFirst。换句话说,我们已经不再是“风口上的猪”。移动开发的光环和溢价开始慢慢消失,并且正在向AI、......
  • 三数之和(双指针法)
    给你一个包含n个整数的数组 nums,判断 nums 中是否存在三个元素a,b,c,使得 a+b+c=0?请你找出所有满足条件且不重复的三元组。注意:答案中不可以包含重复的三元组。示例:给定数组nums=[-1,0,1,2,-1,-4],满足要求的三元组集合为:[[-1,0,1],[-1,-1,2]]......
  • C语言程序设计 答疑安排(2009春季 1-10周)
    C语言程序设计答疑安排(2009春季1-10周)地点:8-309,或者8-409,如果8-309,8-409没开门则到8-308教室。时间:黑老师,第六周,周四下午,2:10-4:00金老师,第七周,周二下午,4:10-6:00王老师,第八周,周三晚上,7:30-9:00王老师,第九周,周三晚上,7:30-9:00李老师,第十周,周三下午,4:10-6:00李老师,第十周,周五下午,2:10-4:00其......
  • C语言程序设计 实验题目
      -----------------------------------------编号:一题目:选择结构程序设计目的:见指导书110页。实验内容:教材:习题3.6,习题3.7习题3.6:参考例1.2,使用if语句,或者使用条件表达式。习题3.7:参考教材例题3.13,教材299页的math.h,不要使用10<=x<20.“无定义”,其余值用printf显示“无......
  • C语言程序设计 2009春季考试时间和地点
     课程名称考试时间监考教室考试人数C语言程序设计第11周周6(2009-05-09)19:00-21:00曲江10-40173C语言程序设计第11周周6(2009-05-09)19:00-21:00曲江10-40727C语言程序设计第11周周6(2009-05-09)19:00-21:00曲江10-40827C语言程序设计第11周周6(2009-05-09)19:00-21:00曲江10......