W3 D3 字符数组、指针


拓展:
在VIM里快速进入man手册:先Esc退出 --> 光标到对应的函数 -->shift + q 进入
unlimited:查询资源占用情况
自查string手册里的所有相关函数

一、字符数组

1、字符数组的定义初始化

字符数组也允许在定义时作初始化赋值

定义方式:

char c[10]={'c', '  ', 'p', 'r','o', 'g', 'r', 'a','m'};
char str[] = "abcdb11111";
char str1[] = "abcda11111";

输出方式:

char c[ ] = "I am happy"; 
printf("%c", c[i]);        //逐个字符输出。

char c[ ] = "I am happy";
printf("%s", c);         //将整个字符串一次输出 必须得是字符数组名
puts(c);              //对字符串进行输出时可以用puts字符串常量后面一定有一个''\0'

在 C 语言中,字符串总是以’\0’作为结尾,所以’\0’也被称为字符串结束标志,或者字符串结束符

单个字符进行输出是不能用puts puts输出时必须用’\0’来进行结束标记

puts

对字符串进行输出时可以用puts(字符串常量后面一定有一个’’\0’)

char sstr[] = “hello”;

puts(sstr);
请添加图片描述

2、字符数组相关函数

strlen:

作用:用来计算指定的字符串s 的长度,不包括结束字符"\0"。

返回值:返回字符串s 的字符数。

strlen() 函数计算的是字符串的实际长度,遇到第一个'\0'结束。如果你只定义没有给它赋初值,这个结果是不定的,它会从首地址一直找下去,直到遇到'\0'停止。而sizeof返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个操作符,strlen()是函数。

char str3[] = "12345";    //strlen(str3)=5, sizeof(str3)=6
char str3[] = "12\0t45";  //strlen(str3)=2, sizeof(str3)=7   
char str3[10] = "12t45";  //strlen(str3)=5, sizeof(str3)=10    
    

strcpy/strncpy:

作用:字符串复制strcpy把从src地址开始且含有’\0’结束符的字符串复制到以dest开始的地址空间
返回值类型:目标串的地址char*
函数原型:char* strcpy(char* des,const char* src) //des为目标字符串,source为原字符串

char str[32] = "hello";
char str1[12];
printf("str = %p\n",str);
printf("str1 = %p\n",str1);

strcpy(str1, str);        //将str复制到str1
	
puts(str);
puts(str1);

在这里插入图片描述
strncpy:将源字符串中最多count个字符复制到目的字符串中,返回指向目的字符串的指针。

//原型
char *strncpy(char *dest, char *src, int n);
//如果src的前n个字节不含NULL字符,则结果不会以NULL字符结束。
//strncpy总是复制 n 个字符到dst指向的内存
//如果src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。
//src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

strcat/strncat:

作用:把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。
返回值:该函数返回一个指向最终的目标字符串 dest 的指针
函数原型:char *strcat(char *dest, const char *src)

char str[128];
char h[] = "hello",s[] = " ",w[] = "world";

strcpy(str,h);
strcat(str,s);
strcat(str,w);

puts(str);

在这里插入图片描述

**strncat:**如果str2的字符数大于n,那么该函数只将str2的前n个字符附加在str1末尾,如果str2中的字符数小于n,该字符会将str2的所有字符附加在str1末尾。

//原型
char * strncat(char *str1,const *char *str2,size_t_n);
//无论哪种情况,都会在新字符串的末尾添加空字符。必须为str1分配足够的空间以存储新的字符串。strncat()函数返回指向str1的指针。

strcmp/strncmp:串比较

作用:比较字符串,比较的时候逐个字符比较
函数原型:int strcmp(const char *str1, const char *str2)

如果str1>str2,返回>0;
如果str1<str2,返回<0;
如果str1=str2,返回=0;

//在具体实现过程中,我们需要遍历两个字符串,直到其中一个字符串结束,每一次循环都要比较两个字符串中字符大小
char str[] = "abcdb11111";
char str1[] = "abcda11111";

printf("%d\n",strcmp(str1,str));     //相当于str-str1  输出:-1
printf("%d\n",strncmp(str1,str,7));  //将str和str1的前7个字符进行比较   输出-1

strncmp:此函数功能即比较字符串str1和str2的前maxlen个字符

//原型
int strncmp(char *str1, char *str2, int maxlen);
//如果前maxlen字节完全相等,返回值就=0;在前maxlen字节比较过程中,如果出现str1[n]与str2[n]不等,则返回(str1[n]-str2[n])

3、习题

输入一行字符,统计其中单词个数。(该问题主要练习标志位的使用,另外如果该问题用字符来进行实现的话会走很多弯路,用字符串进行逐个字符的遍历较方便一些)

#include <stdio.h>
#include <stdlib.h>

//hello   world   123      456   

int main()
{
	char buf[128];
	int i = 0,count = 0,flag = 0;
	
	gets(buf);

	for(; buf[i] != '\0'; i++)
	{
		if(buf[i] == ' ')
		{
			flag = 0;
		}
		else	// char
		{
			if(flag == 0)
			{
				flag = 1;
				count++;
			}	
		}
	}
	printf("WORD:%d\n",count);
	exit(0);
}

二、指针

只要是指针类型就占8个字节

**变量:**是给人看的,抽象命名

**地址:**就是变量所在位置,指针。

1、指针的基本概念

指针的作用: 可以通过指针间接访问内存

  • 内存编号是从0开始记录的,一般用十六进制数字表示
  • 可以利用指针变量保存地址

2、指针变量的定义和使用

指针变量定义语法: 数据类型 * 变量名;

指针变量和普通变量的区别

  • 普通变量存放的是数据,指针变量存放的是地址
  • 指针变量可以通过" * "操作符,操作指针变量指向的内存空间,这个过程称为解引用

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

程序实现:

int main()
{
    int i = 1;     //指针大小默认8个字节
    int* p = &i;   //一级指针 p的类型是int* p是用来保存地址的变量 用来存放指针的变量
    int** q = &p;  //二级指针不能存放整型数的地址 

    printf(" i   ---> %d\n",i);
    printf(" &i  ---> %p\n\n",&i);
    
    printf(" p   ---> %p  &i ---> %p\n",p,&i);
    printf(" &p  ---> %p\n",&p);
    printf(" *p  ---> %d  i  ---> %d\n\n",*p,i);

    printf(" q   ---> %p\n",&p);
    printf(" &q  ---> %p\n",&p);
    printf(" *q  ---> %p  p  ---> %p\n",*q,p);
    printf(" **q ---> %d  i  ---> %d\n",**q,i);

    exit(0);

}

输出:
在这里插入图片描述
总结

我们可以通过 & 符号 获取变量的地址

利用指针可以记录地址

对指针变量解引用,可以操作指针指向的内存

直接访问、间接访问

3、空指针和空类型

空指针:针变量指向内存中编号为0的空间(指针的值为空,能有效避免野指针的产生。

用途:初始化指针变量。

注意:空指针指向的内存是不可以访问的

int main()
{
	int i = 1;
	int *p = &i;
	void *m = NULL;

	*p = 100;
	printf("%d\n",*p);


	exit(0);
}

输出:100

空类型:void *m =NULL; 可以接受任何类型的指针值(16:39)

void* 类型不能坐取*运算,用来传参和返回值。

空类型的指针不能存放值

4、野指针

野指针:指针变量指向非法的内存空间,仍然在访问,指针的指向不明确。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值