目录
指针与数组:
指针是左值,而数组名不是左值,它是常量。
数组指针与指针数组
- 数组指针:首先它是一个指针,指向一个数组。
- 指针数组:首先它是一个数组,数组元素都是指针。
//指针数组
//初始化:因为指针数组是一个数组,存放的都是指针变量(字符指针),因此初始化的时候,
//就是要给每一个字符指针(字符串)赋值
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;
}