嵌入式学习笔记十四——指针操作一维字符型数组

1.const的作用

以puts函数为例,函数原型是int puts(const char *s);

我们写一个自己的Puts函数,从键盘输入字符串,结构大概是

int Puts(const char *s)
{
	while (*s != '\0')
	{
		putchar(*s);
		++s;
	}
	putchar('\n');
	return 0;
}

在这段代码中++s这个操作是指向下一个元素,如果我们误操作将它写成了++(*s)或是*s++,结果就是改变了指针指向地址的内容。但要求我们输出一个字符串,并不希望误操作导致数组内容被改变,这时候const就发挥作用了。

int puts(const char *s),const表示只读,下面是const的一些用法:

const int a; //a 此时是一个只读的变量 
     		
int a = 10;
//int *p = &a;
const int *p = &a;   //const限定是 基类型 
                     //表示不能通过 *p 的方式 修改基类型数据 	
				 
int const *p = &a;   //const限定是 基类型 
                     //表示不能通过 *p 的方式 修改基类型数据
                     //与const int *p = &a等价
 					 
int * const p = &a; //const限定是 指针变量p 
                    //表示将p限定位只读 
					//表示p不能被修改 			
		
const int * const p = &a;  //基类型和指针变量 都被限定为只读
					       // p = &b; //不能修改 
						   //*p = b;  //不能修改 

2.const限定原则

   就近原则  //const 离谁近 就限定谁 

总结:

1.形参设计为 const char *的目的, 防止函数中的误操作 

2.好处
    (1).提前发现问题 将运行时问题,提前到编译时  
    (2).const char * 可以接收  char *和const char * 提高参数的适用性

注意:形参能写成const的都写const 

应用:

    1.如果 不想 通过*p方式改变基类型对应的数据 可以写成:
      const int *p = &a;  
      int const *p = &a;  

   2.如果 指针变量p 定义好后,不想再指向别的变量则写成
     int * const p = &a;

3.指针操作一维字符数组

练习

用函数和指针,完成

1.Puts/Gets

2.Strlen

3.Strcpy/strncpy

4.strcat /Strncat

5.Strcmp/Strncmp

代码如下:

#include <stdio.h>
#include <string.h>

int Puts(const char *s)
{
	if (s == NULL)
		return -1;
	while (*s != '\0')
	{
		putchar(*s);
		++s;
	}
	putchar('\n');
	return 0;
}

char *Gets(char *s)
{
	char *ret = s;

	while((*s = getchar()) != '\n')
		++s;
	*s = '\0';
	return ret;
}

size_t Strlen(const char *s)
{
	const char *ret = s;
	while (*s != '\0')
	{
		s++;
	}
	return s-ret;
}

char *Strcpy(char *dest,const char *src)
{
	char *ret = dest; 
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';
	return ret;
}

char *Strncpy(char *dest,const char *src,int n)
{
	char *ret = dest;
	while (*src != '\0' && n > 0)
	{
		*dest = *src;
		++dest;
		++src;
		--n;
	}
	while (n > 0)
	{
		*dest = '\0';
		++dest;
		--n;
	}
	return ret;
}
char *strcat(char *dest,const char *src)
{
	char *ret = dest;
	while (*dest != '\0')
	{
		++dest;
	}
	while(*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';
	return ret;
}
char *Strncat(char *dest,const char *src,size_t n)
{
	char *ret = dest;
	while (*dest != '\0')
		++dest;
	while (*src != '\0' && n != 0)
	{
		*dest = *src;
		++dest;
		++src;
		--n;
	}
	*dest = '\0'; 
	return ret;
}
int Strcmp(const char *s1,const char *s2)
{
	int ret = 0;
	while (*s1 == *s2 && *s1 != '\0' && *s2 != '\0')
	{
		++s1;
		++s2;
	}
	ret = *s1 - *s2;
	return ret;
}


int Strncmp(const char *s1,const char *s2,size_t n)
{
	int ret = 0;
	while (*s1 == *s2 && *s1 != '\0' && *s2 != '\0' && n-1)
	{
		++s1;
		++s2;
		--n;
	}
	ret = *s1 - *s2;
	return ret;
}

void Memcpy(void *dest,const void *src,size_t n)
{
	char *p = dest;
	const char *q = src;
	while (n > 0)
	{
		*p = *q;
		++q;
		++p;
		--n;
	}
}


int main(void)
{
    char s[20] = "hello";
	char ss[20]= "english";
//	Gets(s);
//	Puts(s);
//	Strncpy(ss,s,5);
//	Puts(ss);
//	int i = 0;
//	for (i = 0;i < 10; ++i)
//	{
//		printf("s[%d] = %c\n",i,s[i]);
//	}
//	printf("%ld\n",Strlen(s));
//	strcat(ss,s);
//    Strncat(ss,s,5);
//	Puts(ss);
//	printf("%d\n",Strncmp(ss,s,3));

	long a[5] = {1,2,3,4,5};
	long b[5];
	Memcpy(b,a,5*sizeof(a[0]));
	int i = 0;
	for (i = 0;i < 5;++i)
	{
		printf ("%ld\n",b[i]);
	}
	return 0;
}

memcpy函数:

 void *memcpy(void *dest, const void *src, size_t n)
 {
      //一个字节一个字节拷贝 
 }
 void * //NULL 空指针 
        //空类型的指针 --- 万能指针
        //可以接收任意类型的指针  
注意:
    如果用 空类型指针 进行 间接运算,必须 转换成 有明确类型的指针 

总结: 

  1.指针操作一维字符型数组 //字符串
   2.知识点
     //1.指针变量的 类型 是怎么确定的?
     //2.一维字符型数组 字符串 
     //3.处理字符串数据方式
        char s[] = "hello";
        const char *p = "hello"; 
    //4. const 关键字  
         const 关键字使用方法 
         const 形参          
   3.实现字符串相关函数
     gets /puts  
     strlen 
     strcpy /strncpy
     strcat /strncat 
     strcmp /strncmp

4.指针操作二维数组 

int a[2][3];//二维数组 

1.c语言中并不存在,真正的二维数组。
2.二维数组本质 是一维数组的一维数组 
3.二维数组 也 符合数组的特点 //连续性,有序性,单一性 

问题:
1.确定需要定义什么类型的指针?从二维数组的本质出发 
   &a[0]
    //a[0]  --- int[3]
    //&a[0] --- int[3] * 
    //c语言中 不支持 int[3] *  
    //正确写法 int(*)[3]

int(*p)[3] = a; //p指向二维数组 a 
                //p的基类型 int[3]

*p <=> a[0] // 相当于是内部这个一维数组的数组名 
       (*p)[0] 
       *(*p+0) //**p

*(*(p+1)+1) <=> a[1][1]
*(*(p+i)+j) <=> a[i][j]       

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值