初识C语言

什么是C语言


C语言一门计算机语言,主要应用于底层开发。
计算机语言的发展历程:
二进制语言(正电1/负电0)->汇编语言->B语言->C语言->C++、java等语言

第一个C程序


  • hello world
#include<stdio.h>                //standard input output
int main                        // 主函数,是程序的入口,有且仅有一个
 {         
      printf("hello world")    // printf函数----向控制台打印一条语句
      return 0;
  }

数据类型


char           //字符数据类型
short          //短整型
int            //整型
long           //长整型
long long      //更长的整型
float          //单精度浮点数
double         // 双精度浮点数
#include<stdio.h>
int main()
{
    char aaa='A';         
    printf("%c\n",aaa);    // %c  ----打印字符格式的数据 
    return 0;
}
#include<stdio.h>
int main(){
    int age=20;
    printf("%d\n",age);     //  %d  ----打印整型十进制数据 
    return 0;
}
#include<stdio.h>
int main()
{
    double a=5.34;
    printf("%lf\n",a);     //  %lf ----打印双精度浮点数 
    return 0;
}
//----%d----打印整型
//----%c----打印字符 
//----%f----打印浮点型--小数 
//----%p----打印地址 
//----%x----打印十六进制 
  • 每种类型的大小是多少?
#include<stdio.h>
int main()
{
    printf("%d\n",sizeof(char));         //1字节      取值范围是0~(2^8)-1(减一是因为0占一位)
    printf("%d\n",sizeof(int));          //4字节      取值范围是0~[2^(8*4)]-1
    printf("%d\n",sizeof(short));        //2字节      取值范围是0~[2^(8*2)]-1
    printf("%d\n",sizeof(long));         //4或8字节               ·   
    printf("%d\n",sizeof(long long));    //8字节                  ·
    printf("%d\n",sizeof(float));        //4字节                  ·
    printf("%d\n",sizeof(double));       //8字节
}
*计算机中的单位*
计算机是通电的硬件(正电 1     负电 0)
十进制: 0  1  2  3  4  5  6  7  8  9 
十二进制(时钟):0  1  2  3  4  5  6  7  8  9  10  11  12
七进制(星期):0  1  2  3  4  5  6  
二进制:0  1

bit----------比特位(即电信号0和1)
byte---------字节(规定8个bit=1个byte)
kb-----------(1个kb=1024个byte)
mb-----------(1个mb=1024个kb)
gb                       ·
tb                       ·
pb                       ·
  • 为什么出现这么些个类型?
    比如说,要设置一个变量来存放人的年龄,这时就要用到整型,整型中有 short、int、long、long long,如果用int、long以及long long,显然范围太大造成存储空间的浪费。
  • 二进制向十进制转化
10000101=(1*2^7)+(1*2^2)+(1*2^0)=133
  • 十进制向二进制转化
131=128+2+1=(2^7)+(2^1)+(2^0)

变量、常量


常量

生活中不变的量,如圆周率π,自然常数e,身份证号

  • 常量分类
    字面常量 (例如:3)
    const修饰的常变量
#include<stdio.h>
int main (void)
{
const   int aa=4;        //const修饰常变量 
    printf("%d\n",aa);     
//  aa =8;     //这里不能对aa变量 重新赋值,变量有了常属性就不能再重新赋值了
    printf("%d\n",aa);  
    return 0;   
}
#include<stdio.h>
int main(void)
{
    const int n=10;      //n是变量,但是又有常属性,所以我们说n是常变量 
    int nn[n]={0}; 
 //在定义数组的时候,括号内的元素个数必须是常量,这里因为n还是一个变量(虽然有了常变量的特性),所以程序不通过
    return 0;
} 

#define定义的标识符常量

#include<stdio.h>
#define max 10
int main(void)
{
    int nn[max]={0};    //这里定义的标识符常量是可以使用的,与上面的额const定义的常变量性质不同
    printf("%d\n",max);
    return 0;   
} 

枚举常量 (一一列举出来的常量)

#include<stdio.h>
enum sex      //枚举常量 
{
    man,
    woman,
    select
};

int main(void){
    enum sex people=men;        //将枚举常量men赋值给变量people
    printf("%d\n",man);
        printf("%d\n",woman);
        printf("%d\n",select);
    return 0;
}

变量

#include<stdio.h>
int main()
{    short age =20;    //向内存申请2个字节=16bit,用来存放20
     float weight =95.6f;  //编译器默认95.5双精度类型,这时将其定义为单精度类型,存在精度丢失,所以以95.6f声明定义为单精度类型
     return 0;
}
  • 变量的定义方式
int  aaa=50;
float  a=50.6f
char ad=‘ss’
  • 变量的分类
    全局变量 (在{}外定义的变量)
    局部变量 (在{}内定义的变量)
#include<stdio.h>
int a=100;      //全局变量
int main(void){
     int ab=10;  //局部变量
     printf("%d\n",ab);
     return 0;
     }
  • 变量的使用
    举个例子:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
    int num1=0;
    int num2=0;
    int sum =0;
    scanf("%d%d",&num1,&num2);     //&取地址,向存放num1和num2的地址输入数值      scanf---输入函数 
    sum=num1+num2;
    printf("%d",sum);
    return 0;
}

就像在中国960万平方公里的土地上,因为有了一个人的地址信息,我们就可以准确找到内蒙古科技大学23号楼xxx室,
内存也像是这样,如4g/8g内存分成了一块一块的地址块,使用&符号就可以准确找到变量在计算机中存放的地址
  • 变量的作用域和生命周期
    作用域
#include<stdio.h>
int aa = 10;         //全局变量的作用域是整个工程
int main()
{
    int num = 100;
    printf("num=%d\n",num);   //局部变量num的作用域就是main函数的{}
    printf("aa=%d\n", aa);
        return 0;
}

生命周期
局部变量生命周期:进入作用域生命周期开始,出作用域生命周期结束
全局变量生命周期:整个程序的生命周期

注意:局部变量和全局变量可以以同名同时存在,建议不要重名,容易误会
当局部变量和全局变量名字相同的时候,局部变量优先
C语言语法规定,变量要定义在当前代码块的最前面

字符串+转义字符+注释


  • 字符串
    字符串是由双引号包住的
字符串"asd"
空字符串""
printf("%s\n",)
#include<stdio.h>
int main(void){
    char aa[]="abc";             //aa数组中的值为 a b c /0 
    char bb[]={'a','b','c'};     //bb数组中的值为 a b c 
    printf("%s\n",aa);//abc末尾默认放一个/0(字符串的结束标志),所以打印abc
    printf("%s\n",bb);//将单个字符以字符串的形式打印,没有遇到字符串的结束标志,则打印随机值,打印abc烫烫烫烫蘟bc

    printf("%d\n",strlen(aa));          //strlen计算字符串长度 ,abc,/0不算
    printf("%d\n",strlen(bb));           //由于没有字符串结束标志/0,所以这个字符串的长度将无法确定,是一个随机值
    return 0;
}

ASCII码,规定每个字符以十进制的形式存储起来(对计算机就转换成对应的二进制)
例如:
/0----0
65-----A
66-----B
97-----a

  • 转义字符
例如:
\n     换行
\t     水平制表符 
\v    垂直制表符
\"     双引号
\\    反斜杠(防止\被转义)
\ddd   八进制数字     例如  \60
\xdd    十六进制数字  例如  \x32
int  main(void){
    printf("%d\n",strlen("c:\test\32\test.c"));   //13个字符(\t算一个转义字符,\32算一个转义字符)打印值为13(\t,\32,\t一共是三个字符) 
    
    printf("%c\n",'\32');     //先将8进制的32转换成十进制数字26,作为ASCII码值26代表->,对应的字符将是输出的结果 
    printf("%c\n",'\x61');   //先将16进制的61转换成十进制数字97,作为ASCII码值97代表a,对应的字符将是输出的结果 
    
    return 0;
}
  • 注释
注释方法一:
/*    可以包住一大段代码
*/

注释方法二:
\\  注释一行代码

选择语句


#include<stdio.h>
int main(void)
{
    int input =0;
    printf("加入比特\n");
    printf("你要好好学习吗?(1/0)>:");
    scanf("%d",&input);
    if(input==1)
    printf("好offer\n");
    else
      printf("卖红薯\n");
    return 0;
    
} 

循环语句


#include<stdio.h>
int main(void)
{
    int line=0;
    printf("加入比特\n");
    while(line<20000)
    {
        printf("敲一行代码");
        printf("%d\n",line);
        line++;
    }
    printf("好offer");
    return 0;
}

函数


#include<stdio.h>
int main()
{
    int sum=0;
    int num1=100;
    int num2=200;
    int a=10;
    int b=20;
    sum=Add(num1,num2);      //调用Add函数
    printf("sum=%d\n",sum);
    sum=add(a,b);
    printf("sum2=%d",sum);
    return 0;
}

int Add(int x,int y)     //自己定义一个Add函数
{
    int z=x+y;
    return z;
}

数组


#include<stdio.h>
int main(void){
    int aa[10]={1,2,3,4,5,6,7,8,9,10};   //定义一个放10个元素的整型数组   (除了可以定义int型的数组,还可以定义char,float等)
    int i=0;
    while(i<10)
    {
        printf("%d\n",aa[i]);     //打印下标为i的元素,此aa数组一共10个元素,对应的下标为0 1 2 3 4 5 6 7 8 9,下标是为了方便访问单个元素
        i++;
    }
    return 0;
}

操作符


  • 算术操作符
   +  -   *   /  %
  • 移位操作符(二进制数字)
<< 左移             >> 右移

Int a=1;
整型1占4个字节----32个比特位
00000000000000000000000000000001
a<<1
00000000000000000000000000000010
Int b=a<<1;
B的输出结果为2

  • 位操作符
&按位与     (规则:对应的二进制位1与0为0,1与1为1)(即:全真为真,一假为假)
(十进制)3----011(二进制)
(十进制)5-----101(二进制)
3&5=001-------十进制1

|按位或    (规则:对应的二进制位1或0为1,0或0为0)(即:一真为真,全假为假)

^按位异或
  //按位异或规则:对应的二进制位相同,则为0,对应的二进制位相异,则为1      

#include<stdio.h>
int main(void)
{
    int a=5;       //101
    int b=3;       //011
    int c=a|b;     //111=7
    printf("%d\n",c);
    int d=a^b;
    printf("%d\n",d);      //按位异或规则:对应的二进制位相同,则为0,对应的二进制位相异,则为1          a^b=110=6 
    return 0;
}
  • 赋值操作符
=    +=    -=   *=   /=   %=   ^=     |=   >>=    <<=
#include<stdio.h>
int main(void){
    int a=10;
    printf("%d\n",a);
    printf("%d\n",!a);  //输出0,即为假 
    return 0;
}
  • 单目操作符
!         逻辑反操作
-          负值
+          正值
&          取地址
sizeof类   型长度(以字节为单位)
~          对一个数的二进制取反
--         前置、后置--
++         前置、后置++
*          间接访问操作符(解引用操作符)
(类型)     强制类型转换
#include<stdio.h>
int main(void)
{
        int a=10;
        printf("%d\n",a);
        printf("%d\n",sizeof(a));    //sizeof是计算空间的大小,单位是字节 
        printf("%d\n",sizeof(int));
        
    int aa[10] = { 0 };
    int s = 0;
    printf("%d\n", sizeof(aa));   
    s = sizeof(aa) / sizeof (aa[0]);   //计算数组内元素的个数    数组大小/单位元素大小 
    printf("元素个数=%d\n", s);
    return 0;
}
#include<stdio.h>
int main (void)
{
    int a =10;
    int aa[]={1,2,3,4,5,6};
    printf("%d\n",sizeof(a));   //int型  4字节 
    printf("%d\n",sizeof(int));
    printf("%d\n",sizeof a);    //sizeof属于一个操作符,如果是一个函数,是需要括号的 
//  printf("%d\n",sizeof int);   error
    printf("%d\n",sizeof(aa));
    printf("%d\n",sizeof(aa)/sizeof(aa[0]));  //aa数组大小/aa数组第一个元素的大小==aa数组的元素个数 
    return 0;
}
#include<stdio.h>
int main(void)
{
    int a=0;          //int 占4个字节,==32比特位         二进制表示00000000000000000000000000000000 
    int b=~a;        //~是按位取反                        二进制表示11111111111111111111111111111111 
    printf("%d\n",b);
    
    //源码 反码  补码
    //负数在内存中存储的时候,存储的是二进制的补码
    //第一位为符号位  0为正数   1为负数
    //打印的时候,打印的是源码
    //打印b  首先要将b存储起来,打印的时候再来打印
    //11111111111111111111111111111111存储的结果是11111111111111111111111111111110存储时,先将b的符号位不变,然后减1 ,符号位不动,其余位取反 
     //得到10000000000000000000000000000001 
} 

//只要是整数,内存中存储的都是二进制的补码
//正数的源码  反码  补码 相同
//负数
//原码 --------- ------》反码--------》补码
//写出二进制序列   其他位按位取反   反码+1 
#include<stdio.h>
int main(void){
    int a=10;
//  int b=a++;   //后置++,先使用,再++   结果a=11  b=10
    int b=++a;   //前置++,先++,后使用   结果a=11  b=11 
    printf("a=%d b=%d",a,b);
    return 0;
} 
#include<stdio.h>
int main(void)
{
    int a=(int)3.14;  //强制类型转换 ,此处3.14是浮点型,编译会有警告,使用强制类型转换,会处理掉这个错误,最终输出结果为3
    printf("%d",a);
    return 0;
} 
  • 关系操作符
>    >=    <=    <    !=    ==
  • 逻辑操作符
&&     逻辑与
||     逻辑或
#include<stdio.h>
int main(void)
{
    int a=3;    //真------非0 即为真
    int b=0;    //假------0 
    int c=a&&b;    //逻辑与 
    int d=a||b;    //逻辑或 
    printf("%d\n",c);        
    printf("%d\n",d);
    return 0;
} 
  • 条件操作符(三目操作符)
#include<stdio.h>
int main(void)
{
    int a=10;
    int b=250;
    int max=0;
    max=(a>b?a:b);    //条件操作符又称三目操作符 
    printf("%d\n",max);
    return 0;
}

等价于下面

#include<stdio.h>
int main (void)
{
    int a=10;
    int b=20;
    int max=0;
    if (a>b)
    max=a;
    else
    max=b;
    printf("%d\n",max);
    return 0;
} 
  • 逗号表达式
exp1,exp2,exp3...
  • 下标引用、函数调用和结构成员
#include<stdio.h>
int main(void){
    int aa[10]={2};
    printf("%d\n",aa[5]);   //[]下标引用操作符
    int a=10;
    int b=20;
    int sum=add(a,b);      //()函数调用操作符 
    printf("sum=%d\n",sum);
    return 0;
} 
int add(int x,int y){
    int z=0;
    z=x+y;
    return z;
}

常见关键字


关键字不能与变量名冲突

auto      auto int a=10  定义局部变量使用,不过现在我们一般省略掉了
break   case   char    const   continue  default   do   double
else   enum   float   for   goto   if   int   long  return   short
static   struct  switch   typedef   union   void   volatile   while
signed   int a=10;实则是signed int a=10;  //定义一个有符号的数字
unsigned  int  num=-1;  //定义一个无符号数,即使放一个负数,num也当做是正数
extern    引入外部符号,在全局变量跨源文件使用时候会用到
register    寄存器管理关键字,计算机存储数据,硬盘(500G)->内存(8G/4G)->高速缓存->寄存器
CPU从内存中拿到数据,然后计算,随着科技的发展,CPU处理数据越来越快,所以CPU逐渐去高速缓存去拿数据,这样处理起来就更快
register int a=10;   //建议把a定义到寄存器里,最终由计算机根据实际情况判定
  • 关键字 tppedef
    类型名重命名
#include<stdio.h>
int main ()
{
    unsigned  int num1=10;    
    typedef unsigned int u_int;
    u_int num2=20;      //这里的num2与num1都是无符号int型
    return 0;
}
  • 关键字 static
#include<stdio.h>
int main(void)
{
    int i=0;
    while (i<5)
    {
        testa();
        i++;
    }
    return 0;
}

void testa(){
  static int a=1;        //a是一个静态的局部变量   static修饰局部变量,局部变量的生命周期变长 
    a++;
    printf("a= %d\n",a);
}
//extern 申明外部符号,在一个.c文件创建全局变量,在另一个.c文件中申明其为外部符号,即可在两个文件中使用这个全局变量
//extern同样可以申明外部函数,效果与申明全局变量一样
//static修饰全局变量,将会改变全局变量的作用域,使得全局变量只能在一个.c文件中使用,这时外部声明不再起作用 
//static修饰函数,改变了函数的链接属性(外部链接属性->内部链接属性)效果与static修饰全局变量相同

#define定义常量和宏

  • 定义标识常量
  • 定义宏
#include<stdio.h>
#define MAX(X,Y) (X>Y?X:Y)     // 定义宏MAX
int Max(int x,int y)           //定义函数Max
{
    if (x>y)
    return x;
    else
    return y;
}

int main(void)
{
    int a=10;
    int b=20;
    //函数解决
    int max=Max(a,b);
    printf("较大值为:%d\n",max);
    //宏解决 
    int max1=MAX(a,b);
    printf("max:%d",max1);
    return 0;
}

指针


先了解内存
内存:
一个大的酒店,因为有规定好的房间号,所以,酒店服务人员可以快速而准确的找到每一个
房间,并为之提供必要的服务。

内存也像是一个酒店一样,整个内存被分成一块一块的内存地址块,将每一个 地址块进行编
号,计算机就能快速的找到地址,我们在创建变量的时候就是这样:向计算机申请一块地址空
间(该地址空间有特定的地址编号),来存放变量,当我们向想输出/使用该变量的时候,计算
机就可以根据我们的指令,找到相应的地址空间,取出存放在该地址空间的变量,为之使用。

32位操作系统和64位操作系统
32位:有32根物理电线,将整个内存排序的时候,将会产生2^32个空间位置(每根电线有正负
信号之分,即0和1),而内存空间将会被分为单独的地址块,每个地址块如果只存放1bit,
则一块内存也就只能存储2^32bit(0.5gb),这样是不合理的。所以,一个内存块存储1byte,
这样一块内存将会存储0.5*8=4gb,显然这样安排是合理的。
64位:同上
#include<stdio.h>
int main(void)
{
    int a=10;
    int* p=&a;    //有一种存放地址的变量-----指针变量 
    printf("%p\n",&a);
    printf("%p\n",p);
    *p=50;   //解引用操作符 ,对a地址存放的值进行更改
    printf("改变以后的a的值为:%d\n",a);
    return 0;
}
int main(void)
{
    char a = 'a';
    char *ba = &a;
    printf("原始a的值:%c\n", a);
    char b = *ba = 's';
    printf("解引用改变地址中存储的内容,结果为:%c\n", b);
    printf("%d", sizeof(ba));
    return 0;
}
  • 指针变量的大小:
32位:由于32位系统的一个内存空间存放的是32个比特位,也就是4byte 
64位:由于64位系统的一个内存空间存放的是64个比特位,也就是8byte

结论:指针在32位操作系统是4byte大小,指针在64位操作系统是8byte大小,(不论指针类型是什么)。

结构体


如果要表示一个复杂对象,如 人、书...
这时候就需要创建出一个复杂对象---结构体

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
struct book           //创建一个结构体类型
{
    char name[20];    //书名
    short price;      //价格
    int  ISBN;       //ISBN号
};                    //注意:此处有分号

int main()
{
    struct book b1 = { "C语言程序设计", 55 };
    printf("书名:%s\n", b1.name);
    printf("价格:%d元\n", b1.price);
    b1.price = 15;                  //变量可以直接赋值修改 
    strcpy(b1.name, "C++");        //数组需要使用strcpy库函数进行修改
    printf("修改后的书名:%s\n", b1.name);
    printf("修改后的价格是:%d元\n", b1.price);
    struct book*p = &b1;
    printf("%s\n", (*p).name);
    printf("%d\n\n\n", (*p).price);
    printf("%s\n", p->name);
    printf("%d\n", p->price);
    return 0;  
}

//.         结构体变量.成员
//->        结构体指针->成员

整体感悟


现在跟着鹏哥学习C语言,和以前是完全不一样的,之前我们的上课形式是在教室里,老师在讲台上对着PPT读课件,我们在下面跟着听,不仅没有电脑实际操作,还得让我们下来好好看书,顺便照着电脑敲代码,这样下来,我们的学习效果和学习的积极性都被磨灭了。尤其是越学到后来,什么指针、结构体、取地址这些的,我们都已经学的云里雾里了,根本不懂。
现在看来,这样的学习刚好是很有成效的:一边跟着视频学习,一边记笔记,同时还有一点,学习C语言这几天,我发现,还是要先对C语言要有一个 整体的认知,然后再细学,就像现在这样,先初识C语言,然后在逐步细化。
其实指针也不难,就是一种变量,能存放内存地址的特殊变量。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容