#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/*字符指针*/
/*
字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以 \0 作为串的结束。*/
//方法一:
// char *ps = "bcd";//1.分配内存给字符指针;2.分配内存给字符串;3.将字符串首地址赋值给字符指针; ps 字符串指针,是指针,是一个变量
//方法二:
char *ps;
ps = "bcd"; //若字符串常量出现在在表达式中,代表的值为该字符串常量的第一个字符的地址。所以 bcd 仅仅代表的是其第一个字符的地址。
printf("*ps输出字符:%c \n", *ps); /*输出字符,使用"%c"*/
printf("*(ps + 1)输出字符:%c \n", *(ps + 1)); /*输出字符,使用"%c"*/
printf("ps输出字符串:%s \n", ps); /*输出字符串,使用"%s";而且ps之前不能有星号"*" */
/*字符数组*/
/* 字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。(即用字符数组来存放字符串)。
在 C 语言中,将字符串作为字符数组来处理。(C++中不是)*/
// 可以用字符串常量来初始化字符数组:
//有初始化的数组定义可以省略方括号中的数组大小。
char str[] = {"Iamhappy"};
// 可以省略花括号
char str2[] = "Iamhappy";
// #系统自动加入 \0
//上述这种字符数组的整体赋值只能在字符数组初始化时使用,不能用于字符数组的赋值,字符数组的赋值只能对其元素一一赋值。
//如果定义的时候没有赋值,那之后怎么给这个数组赋值呢
char str3[20];
// str3="Iamhappy";// 错误用法1:str3虽然是指针,但是它已经指向在堆栈中分配的20个字符空间,现在这个情况str3又指向数据区中Iamhappy常量,这里的指针str3出现混乱,不允许!
// str3[20] = "Iamhappy"; //错误用法2:一个字符怎么能容纳一个字符串?况且str3[20]也是不存在的!
// 正确用法3:对字符数组的各元素逐个赋值。
// (1)单字符赋值,可通过数组下标方式或指针方式,引用数组元素,进行赋值,如:
char a[10];
char ch = 'a';
//可通过数组下标引用数组元素,完成赋值
for (int i = 0; i < 10; i++)
a[i] = ch + i;
printf("a: %s\n", a);
//通过指针对数组相应元素赋值
char *p;
for (p = a; p < a + 10; p++)
*p = ch++;
printf("p: %s\n", p);
// (2)字符串赋值,可使用string.h头文件中的字符串操作函数进行赋值,如:
char b[10];
strcpy(b, "abcdefgh");
printf("b: %s\n", b);
// 在 C 语言中,可以用两种方法表示和存放字符串:
// (1)用字符数组存放一个字符串
char str5[] = "IloveChina";
printf("str5: %s\n", str5);
char str6[] = {'I', 'l', 'o', 'v', 'e', 'C', 'h', 'i', 'n', 'a'}; //这里打印出来有点奇怪
printf("str6: %s\n", str6);
// (2)用字符指针指向一个字符串
char *str7 = "IloveChina";
printf("str7: %s\n", str7);
/*(字符串)指针数组*/
// char *a[]:表示a是数组,数组中的元素是指针,指向char类型,(数组里面所有的元素是连续的内存存放的) 数组名是数组第一个字节的内存地址,并且数组名a也表示指针。所以a 并不表示a地址存储的内容, 而是a地址本身。
// a+1:表示 a 的第二个元素的内存地址, 所以是加 8 字节。( 因为a的元素是char 指针, 所需要的空间为8字节(64位内存地址)。 )
// *(a+1):则表示a这个数组的第二个元素的内容 (是个char 类型的指针,本例表示为world字符串的地址)。
// *(*(a+1)):则表示a这个数组的第二个元素的内容(char指针)所指向的内容(w字符).
// char * a[10]:表示限定这个数组最多可存放10个元素(char指针), 也就是说这个数组占用10*8 = 80字节。
// a+1 => *(a+1) => *(a+1)[0]
// 指针(地址) => 指针内容(字符串) => 字符
char *str8[] = {"Hello", "C", "World"}; //char (*str8)[] = ...
int i;
for (i = 0; i < 3; i++)
printf("%s\n", str8[i]);
// str8[0]字符串"hello"的首地址,str8[0]+1:字符串"hello"第二个字符'e'的地址,str8[2]=str+2:第三个字符串"world"的首地址
// str8[1]字符串"C++"的首地址
// str8[2]字符串"world"的首地址
char **p_str;
for (p_str = str8; p_str < str8 + 3; p_str++)
puts(*p_str); //*p_str为字符串首地址,*p_str[0]为字符串的第一个字符地址
printf("%s,%s,%c", str8[0], str8[0] + 1, *(*(str8 + 2) + 2)); //Hello,ello,r
// char *argv:理解为字符串
// char **argv:理解为字符串指针
// char *argv[]:字符串指针数组
}