C和指针入门1

本文从内存地址、不同数据类型在内存中的存储结构、指针变量的声明与初始化、NULL指针的应用、含指针的表达式以及基础编程练习(如查找字符、删除子串)等方面详细介绍了指针在C语言中的基本概念和应用。还提到了一些有趣的编程技巧,如判断整数奇偶性的方法。
摘要由CSDN通过智能技术生成

从纯小白的角度入手,重新开始记录指针的学习。主干,练习,补充。

一.内存和地址

内存中的每个位置总包含一些值,每个字节通过地址来标识,如下:

100101102103104105

每个位置为1字节(byte),在许多机器上,1byte=8bit,即一个位置包含8个位。每个字只有一个地址,一般为最左边那个字节的位置。我们常把更多字节合在一起作为一个更大的内存单位,如下两个字的存储空间:

100104

 Q:对于不同数据类型在内存中存储的结构图是怎么样的呢?

 

 

 

二.指针变量理解

指针变量用于存放其他变量的地址。

1.声明

指针变量a的值为另一变量b的地址,a的类型为b的类型。如:int *a;表示a是一个指向int类型变量的指针变量。声明一个指针变量不会自动分配任何内存。

2.初始化

在对指针执行间接访问前,指针初始化,或指向现有的内存,或分配动态内存。

a.指向某变量地址。如:int b; int*a=&b;

b.初始化为NULL指针

作为一个特殊指针变量,声明*a=NULL表示a目前不指向任何有效内存地址,指向内存地址为0的地方。与*a=0是等价的。在使用前需用malloc动态分配获得内存。(动态内存是之后学习的又一章节)Q:NULL指针的应用?

int *a = NULL; // 声明一个指向整型变量的指针并初始化为NULL

a = (int *)malloc(sizeof(int)); // 分配一个整型变量大小的内存空间给指针a

if (a != NULL) {
    *a = 10; // 在分配内存后,可以通过指针a来操作对应的内存空间
}

// 使用完指针a后,记得释放内存
free(a);

二者殊途同归,本质上是为了使指针指向明确的、一定大小的存储空间。

 

三.含指针变量的表达式

1.*的用途

在声明时*用来指明该变量为指针变量,之后使用时*用于间接访问指针变量指向的地址中存储的内容。如声明int *a;之后初始化a=&b;则*a与b的值相同,再*a=5则b=5。

ps:强制类型转换

*(int*)100=25;

表示:把100从整型转换为指向整形的指针,再利用*间接访问,把25存进地址为100位置处 。

2.指针变量作为左值、右值进行访问的区别

3.指针运算

(1)算术运算

a.指针+/-整数

标准定义这种形式只可用于指向数组中某个元素的指针,且结果类型也是指针。+1即指针指向数组中下一个元素。

ps:这里需要结合内存理解,不同类型的变量在内存空间中占据的字节数有所不同,而指针变量的值就是地址,故对于指针变量做加减,如果只像一般的算术运算,比如+1就是下一个字节,一个int类型数据占据的内存都不止1个字节,指针不就指向int值内部的某个字节了?

当然,计算机设计者不会让这种麻烦产生啦QAQ!当指针和整数量执行运算时,会根据指针指向类型的大小运算。如:某机器上float占4个字节,声明float*a=&b;已知a=&b=100,a+3实质上得到的新地址为112。即增加的是3个float的大小,而非3个字节。这里小小补充一下:

我们会常用到字符串定义:char*a和char a[]是等价的(ps:前者需要malloc分配内存,后者需要表明数组大小)在前者定义下,可以用下标,如a[0]

该形式亦适用于malloc分配的内存。(目前还没有遇到应用)

b.指针-指针

只适用于当两个指针都指向同一个数组中的元素时,结果类型为有符号整数类型。减法运算的值为两个指针在内存中的距离(以数组元素的长度为单位,而非字节),如:p1=&a[i],p2=&a[j],则p2-p1=j-i。

(2)关系运算

前提是两个指针都指向同一个数组中的元素,使用<,>,<=,>=等关系运算用于判断它们在数组中的相对位置。目前看到的应用就是在for循环的条件表达式中,以位置关系真假作为一个限制条件。

四.基础编程练习

不运用C中的操纵字符串的函数库编写函数

1.查找匹配的第一个字符

查找source字符串中匹配chars字符串中任何字符的第一个字符,然后返回一个指向source中第一个匹配所找到位置的指针。函数原型:char*fin_char(char const*source,char const*chars)。

若所有字符均不匹配,函数返回NULL;若任一参数为NULL或所指向的字符串为空,函数也返回NULL。参数所指向的字符串不会被修改(const用法见文件)

#include<stdio.h>
char* find_char(char const* source, char const* chars);

int main()
{
	char a[100], b[100],* result;
	printf("source:");
	scanf_s("%s", a,sizeof(a));
	printf("chars:");
	scanf_s("%s", b,sizeof(b));
	
	result = find_char(a, b);
	printf("%c\n",*result);
	printf("%p\n",result);
	return 0;
}

char* find_char(char const* source, char const* chars)
{
	char const* p=source;
	char const* q = chars;
	if (source == NULL || chars == NULL)
		return NULL;
	else
		while (*p!='\0')
		{
			q = chars;
			while (*q!= '\0')
			{
				if (*p == *q)
					return (char*)p;
				q++;
			}
			p++;
		}
	return NULL;
}


2. 删除一个字符串的一部分

函数原型:int del_substr(char*str,char const*substr)

需要先判断substr是否出现在str中,若是函数返回1,否则返回0;若出现,函数应把str中位于该子串后面的所有字符复制到该子串的位置,从而删去这个子串,然后函数返回1。若substr在str中出现了多次,函数只删除第一个substr。(写的时候分开了)

#include<stdio.h>

//统计字符串长度--对应于strlen(s)函数
int strlength(char const* str)
{
	int len = 0;
	while (*str++ != '\0')
		len++;
	return len;
}

//寻找字符串--strncmp(a,b,len)
int strfind(char* str1, char const* str2)
{
	int len = strlength(str2);
	for (int i = 0; i < len; i++) {
		if (str1[i] != str2[i]) 
			return 0;
	}
	return 1;
}

//删除字符串--C中无可以直接删除子串的函数,但可利用strcpy复制
void del_substr(char* str, char const* substr)
{
	int strlen = strlength(str);
	int sublen = strlength(substr);
	char* ptr = str;
	char* tmp = str;
	int flag = 1;
	while (*ptr)
	{
		if (flag&&strfind(ptr, substr))
		{
			ptr += sublen;
			flag = 0;
		}	
		else
		{
			*tmp = *ptr;
			tmp++;
			ptr++;
		}
	}
	
	*tmp = '\0';
}

int main()
{
	char str[100], sub[100];

	printf("str:");
	scanf("%s", str);
	printf("sub:");
	scanf("%s", sub);

	del_substr(str, sub);

	printf("Result:%s\n", str);

	return 0;
}

扣几张之前朋友的小组笔记总结(翁恺指针视频)

 

 

 

在阅读关系运算时发现一个有趣的小知识:

C语言--输入任意一个数,判断它的奇偶性(三种方法)_有以下程序段,,要求先输入一个整数,然后再判断是奇数还是偶数: s=①(input("请输-CSDN博客

ps:《C和指针》 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值