C:指针与数组 详解

 

目录

指针与数组:

数组指针与指针数组


 

指针与数组:

指针是左值,而数组名不是左值,它是常量。


数组指针与指针数组

  • 数组指针:首先它是一个指针,指向一个数组。
  • 指针数组:首先它是一个数组,数组元素都是指针。
	//指针数组
		//初始化:因为指针数组是一个数组,存放的都是指针变量(字符指针),因此初始化的时候,
        //就是要给每一个字符指针(字符串)赋值
	char *p[5] = {
		"i am",
		"who",
		"i am",
		"and you",
		"haha"
	};
	int i;
	for (i = 0; i < 5; i++)
	{
		printf("%s.\n", p[i]);//访问数组下标,因为p是一个指针数组,本质上是数组
	}

	//数组指针
		//初始化:数组指针,指针指向的是数组本身,并不是数组的第一个元素的地址,【这个需要和数组区分开】
	char str[5] = {'i','l','o','v','e'};
	char(*q)[5] = &str;//因此,需要将数组的地址给数组指针
	for (i = 0; i < 5; i++)
	{
		printf("%c.\n", *(*q+i));//*q就是数组的地址,*q+i是让遍历数组各元素的地址,*(*q+1)->从地址中取值
	}
	
	//数组和指针
	char str1[5] = { 'u','l','o','v','e' };
	char *r = str1; //数组名即数组第一个元素的地址,可以定义一个指针指向数组名,即让指针r指向数组str1的第一个元素的地址
	for (i = 0; i < 5; i++)
	{
		printf("%c.\n", *(r+i));//r就是数组的第一个元素的地址,r+i是让遍历数组各元素的地址,*(r+1)->从地址中取值
	}

下面这段代码,首先有一个指针数组*pArray[4],这个数组里面有四个字符串,如果希望把这个数组给逐个打印出来的话,怎么办?

其中一个方法就是:定义一个数组指针,指向这个指针数组。

这里实在解释地自己都觉得有些牵强,真的不好理解。今天先写到这,日后再来理解。

	char *pArray[4] = {
		"Hello!",
		"How are you?",
		"Fine, thank you, and you?",
		"i am fine too."
	};///指针数组,数组里面的元素都是指针
	int i;
	//创建一个指向指针数组的指针(数组指针:指向数组的指针)
	char *(*p)[4] = &pArray;//首先是一个指针(*p),指向一个字符指针数组char * [4] => char *(*p)[4]. 接着再把指针数组的地址给这个数组指针
	for (i = 0; i < 4; i++) {
		printf("%s.\n", (*p)[i]);//(*p)是指向的是指针数组,然后再用下标法取出指针数组的值
	}

题目:分割字符串。用户输入一个英文句子,你的程序将这个字符串按空格进行分割,返回由单词组成的二维数组

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#define MAX 1024

int main(void)
{
	//输入一个英文句子,通过空格' '来分别将单词放入一个二维数组,然后分别打印出来。
	char str[MAX]; //input string.
	char *p = str;
	int  len = 0;  //length of input string
	int  cword = 0; //how many words in total
	int  cchar = 0; //maximum char of the word
	int  max = 0;
	int  i=0,j;
	int  count = 0; //单词地址序号
	char *pos[MAX] = { 0 }; //store the first memory of each cword 数组指针
	char indicator = ' '; //任意分割字符
	printf("请输入一个英文句子:");
	/*输入字符串并读取:两种方式*/
	//方法一:从标准流直接读入字符串
	//fgets(str, MAX, stdin);
	//while ((*p++) != '\n')
	//{
	//	len++;//计算输入的字符串有多长
	//}
	//str[len - 1] = '\0';//抵消最后一个'\n'
	//p = str; //把指针重新回归到字符串第一个字符位置
	
    //方法二:从标准流逐个读入字符,比较高效
	while ((str[len++] = getchar()) != '\n' && len + 1 < 1024)
		;
	str[len - 1] = '\0'; // str[len]存放的是'\n',将其替换为'\0'

	printf("请输入分割符:");
	scanf("%c", &indicator);
	//记录第一个单词的地址
	if (*p != ' ')
	{
		pos[count++] = p;
		cword++;
	}
	//从第一个字符开始读,如果不是空格,就记录一下cchar,如果是空格,就记录一下cword
	while (len--) //循环整个字符串
	{
		if (*p++ == indicator)
		{
			max = cchar > max ? cchar : max;//判断字符长度是不是最长
			cchar = 0;

			if (*p != indicator) //用于判断连续空格或已经到最后一个字符
			{
				cword++;//
				pos[count++] = p;
			}
			if (*p == '\0')
			{
				break;
			}
			
		}
		else
		{
			cchar++;
		}
	}
	max = --cchar > max ? cchar : max;//判断最后一个单词的长度, 最后会算多一个'\0',所以减去
	
	//动态数组的大小,有多少个单词,二维数组第一个元素就有多少个;每一个单词多长,二维数组第二个元素就有多大
	char **result;
	result = (char **)malloc(sizeof(char *) * cword);
	for (i = 0; i < cword; i++) {
		result[i] = malloc(sizeof(char) * (max+1));
	}
	
	//char result[cword][max + 1]; //动态分配内存,在linux中能编译通过

	for (i = 0; i < cword; i++)
	{
		//每一个单词有多少字符需要动态判断,只要字符不为“分割字符”或者‘\0',j加1
		for (j = 0; *(pos[i] + j) != indicator && *(pos[i] + j) != '\0'; j++) {
			result[i][j] = *(pos[i] + j);
		}
		result[i][j] = '\0';
	}
	printf("分割结果已经分配到数组result[%d][%d]中,", cword, max+1);
	printf("重新分配之后的单词为:\n");
	for (i = 0; i < cword; i++)
	{
		printf("%s.\n", result[i]);
	}
	return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值