一维、二维char型数组与一级、二级char型指针的饶舌


创建char型数组、char型指针通常是为了存储字符串。
如果只需要存储一个字符串,那么创建一个一维char型数组或char *型指针即可。
如果要存储多个字符串,那方法就变多了,开始饶舌:

存储单个字符串的方法

char str1[ ]

创建一维char型数组。

char str1[] = "Hello world!";
printf("%s\n", str1);	
//显示:Hello world!

char *str2

创建char *型指针。

char *str2 = "Hello world!";
str2 = str1;					//可以将一个字符数组的首地址赋值给char *型指针
printf("%s\n", str2);			//指针与数组使用时看起来一样,都只用写出变量名
//显示:Hello world!
printf("%c\n", *str2);//取消对字符串指针(实际上是字符指针)的引用则只得到数组的第一项元素(相当于str1[0])
//显示:H
printf("%c\n", *(str2 + 1));		//显示下一个字符
//显示:e

用char *型指针显示字符串时不能取消引用,否则只能得到一个字符。

分析一些可能的写法

printf("%s\n", *str2);		//取消对字符串指针的引用,按字符串格式%s输出
//程序运行时会出现异常
printf("%s\n", str2 + 1);	//使指针地址加一,按字符串格式 %s输出
//显示:ello world!
printf("%c\n", str2 + 1);	//使指针地址加一,按字符格式 %c输出
//显示:▊

printf("%c\n", *str1);		//取消对数组名的引用(则只会得到数组的第一个元素,相当于str1[0]),按字符格式 %c输出
//显示:H
printf("%s\n", *str1);		//取消对数组名的引用,按字符串格式 %s输出
//程序运行时会出现异常
printf("%c\n", *(str1 + 1));	//数组名可以像指针一样通过加一选择下一项,小心搞混
//显示:e
printf("%s\n", str1 + 1);
//显示:ello world!

存储多个字符串的方法

char str3[ ][10]

创建二维char型数组,第一维的每项元素可以存储一个字符串。

char str3[][10] = {"Hello", "world!"};

char *str4[ ]

创建char *型指针数组,每项元素可以指向一个字符串。

char *str4[] = {"Hi", "girls!"};
//注意标识符str4是一个数组名,而不是指针变量名,这个数组中的各项元素都是指针
str4[0] = str3[0];
str4[1] = str3[1];
printf("%s,%s\n", str4[0], str4[1]);//一维指针数组使用时看起来跟二维char型数组一样
//显示:Hi,girls!

char **str_list

创建二级char **型指针。

char **str_list = str4;	//相当于用一个指针指向char *str4[]
  • 赋值语句不能为 char **str_list = {“Hi”, “girls!”}; 或 char **str_list = str3;,否则程序运行时会出现异常,因为等号右边是一个字符串数组,而等号左边需要的是一个字符串指针数组(准确地说是char *型指针的数组)。
  • 创建二级指针时,其下属的各个一级指针都尚不存在,必须得先分配一块内存才能赋值。比如下方是使用二级char **型指针的例子,存储一个字符串列表。
//假设需要创建一个包含n=4个字符串的列表
int n = 4,i=0;
char **str_list = malloc(sizeof(char *)); //给str_list这个指针动态分配内存
*str_list = malloc(sizeof(char *) * n); //给字符串列表中的第一个字符串指针动态分配内存,一次性分配了n个指针的空间,从而使它们的地址连续
*str_list = "Hi";				//让第一个字符串指针指向一个字符串
*(str_list + 1) = "girls!";		//让第二个字符串指针指向一个字符串
*(str_list + 2) = "Hello!";		//让第三个字符串指针指向一个字符串
*(str_list + 3) = NULL;			//让第四个字符串指针成为空指针

for (i = 0; i < n; i++)
{
    printf("%s\n", *(str_list + i));
}

分析一些可能的写法

printf("%s,%s\n", str4, *str4);	//str4数组中的各项元素都是指针,存储的是地址
//显示:yP@,Hi
printf("%s\n", str_list);//str_list是一个指向指针的指针,因此它显示的值是一个地址
//显示:yP@
printf("%s\n", *str_list); 		//取消对str_list的引用,得到一个字符串
//显示:Hi
printf("%c\n", **str_list);		//两次取消引用,就只能得到一个字符了
//显示:H
printf("%s\n", *(str_list + 1)); //通过指针加一,选中下一个字符串
//显示:girls

显示结果如图:
在这里插入图片描述

关于使用指针

  • 存储字符串时,用指针比用数组更高效,因为可以在知道了要存储多大的字符串后再动态分配内存。否则事先创建一个数组来存储字符串,会占用大量的静态内存空间。
  • 指针名是变量,可以修改它的值。而数组名是常量,不可修改,比如进行自加时会报错。
  • 指针加一时并不是把地址增加一个位,而是增加一倍的 sizeof(指针所指变量) 。比如char *型指针加一时,地址增加一倍的sizeof(char),即1个字节;结构体指针加一时,指针增加一倍这个结构体的大小,正好指向下一个结构体。
  • 取消引用运算符 * (又称为间接运算符)是取消指针对某个地址的引用,而获得这个地址所存储的数据的值。可如果一个指针指向另一个指针,那么取消引用后获得的数据仍然是一串地址。

关于int main(int argc, char *argv[ ])

main函数常见的三种函数头:

void main(void)		//没有返回值,没有形参
int main(void) 		//有返回值,没有形参
int main(int argc, char *argv[])	//有返回值,有形参

一般来说,main函数不会被调用,因此不需要设置形参和返回值。但在命令行窗口运行C语言程序时,可以给程序传递一些值,这就需要用到第三种函数头。例如:

C:\Users>D:\1.exe a b 3 4

argc用于存储从命令行输入的参数的个数。(在上例中为5)
argv[ ]用于存储argc个参数,其中argv[0]存储的是程序名。(在上例中为D:\1.exe)
这里argv就是一个char *型指针的数组,其中存储的参数都是字符串的形式。

第三种函数头还可写作:

int main(int argc, char **argv)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值