一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C語言基礎解析之分支與循環語句

C語言基礎解析之分支與循環語句

2022-01-12 14:26愛內卷的王同學 C/C++

C語言是一門結構化的程序設計語言,當C語言用來描述生活中的事物時,會用到三種結構:順序結構(不去贅述),選擇結構(對應分支語句),循環結構(對應循環語句),分支語句:分支語句分為兩種,一種是if語句,一種是

- if語句:if(表達式)

// 括號里面放一個表達式
?//表達式的結果如果為非零,表達式為真
? //表達式結果如果為零,表達式為假

if語句可以單支,雙支,多分支,還可以用大括號括起來之后執行多條語句,下圖為雙分支示例:

if(表達式)
  語句;//每一個分號隔開的叫做一條語句
else
  語句;//注意!無大括號直接寫只能執行一條語句

下圖為多分支示例:

if(表達式)//第一條語句也沒有分號
  語句;
else if(表達式);
  語句;//注意else if語句結束要有分號
else if(表達式);
  語句:
//此處省略若干個else if
else//此處便是最后一條語句了,無分號
  語句;

下圖為執行多條語句的示例:

if(表達式)
{
  語句01;
  語句02;
  //....
}
//下面的可以單支,雙支也可以多分支

懸空else問題

示例:

#include <stdio.h>
int main()
{
  int a = 0;
  int b = 2;
  if(a == 1)
      if (b == 2)
          printf("hehe\n");
  else
      printf("haha\n");
  return 0;
}

以上這段代碼的打印結果大多數人可能第一眼看到之后,就會說屏幕上會打印 :haha,因為他們會認為:第六行的表達式判斷之后,a是不等于1的,故表達式為假,執行else后面的語句。但是其實不然,else只于離他最近的那個 if 匹配,因此以上的代碼的真實打印結果為:不打印。

所以好的代碼書寫風格可以大大減少不必要的誤會

//正確的書寫方式
if(a == 1)
  if(b == 2)
      printf("hehe\n");
  else
      printf("haha\n");

 

- switch語句

switch語句也是一種分支語句,多用于多分支的情況

switch語句的語法格式:

switch(整形表達式)//后面無需再放分號
{
case (整形常量表達式):
      語句;
      break;
//break是決定了程序走到該位置之后還要不要往下走
//有break直接跳出switch
//無break繼續往下執行其他的case語句
//直至遇到break為止
}

要注意的細節:

(以代碼為例)

#include <stdio.h>
int main()
{
  int day = 0;
  scanf("%d",&day);
  switch (day)
  {
      case 1:
       //以下略
  }
  return 0;
}

要注意的細節

(對照上圖)

  • 如果將第4行的代碼改成:float day,那么改程序將無法繼續執行,因為這樣改完之后原來的day就被改為了浮點型,day傳到第6行之后還是一個浮點型,而使用switch的語法明確規定:switch(),括號中要寫整型常量表達式,必須為整型和常量
  • 還有,如果在switch語句執行開頭提前定義好一個整形變量,并給它賦值,之后再把這個變量放入case 的后面,此程序也是無法執行的。下圖示例:
int n = 1;
switch (/*此處略*/)
{
  case n:
//上面的操作一定會引起編譯器的報錯
//因為n本質上還是屬于是一個變量
//case后根據語法規范必須為整形且常量
}
  • 另外,如果case后面跟的滿足整型,常量,并且是一個表達式的話,也是可以執行的下去的‘
//示例
case 1+0:
//這樣寫也是可以編譯的
  • 最后就是,如果case后面跟的是一個字符型也是能夠編譯過去的,因為字符也是屬于整形的一種,字符以ascii碼的形式儲存在計算機之中的。

switch中的的default子句:

此子句適用于處理那些所有分支情況之外的輸入

示例:

//多余的代碼略寫
int day = 0;
scanf("%d".&day);
switch(day)
{
  case 1:
//case內的語句和break略寫        
  case 2:
  case 3:
  case 4:
  case 5:
  case 6:
  case 7:
  default:
      printf("輸入錯誤\n");
   break;   
}

如上圖所示,case語句之中只給出了七個分支來選擇,但是如果輸入者一不小心輸入錯誤,沒有輸入1至7中的數(比如輸入了一個9),那么程序最后就會不編譯,為防止出現這種情況的發生,所以專門設計了一個default子句用來供那些別的錯誤情況進入,以給予輸入者一個錯誤提示。另外,default子句不管放在開頭還是結尾都沒問題,但是我們一般默認放置句尾。

循環語句:循環結構分為三種:while循環,for循環,do while循環

 

- while循環語法結構

while(//表達式,即判斷循環執行的條件)
{
  循環語句;
}

上面的表達式結果如果為真,即非0,那么循環執行

如果表達式結果為假,即為0 ,那么循環體不執行

注意事項:

如果在while循環中有break,那么該break用于調出當前所在的循環體

就是說只能跳一級,跳出它當前所在的循環。如果外面還有循環體,那照樣還要繼續執行下去

如果在while循環中有continue,那么continue的作用就是用于跳過continue后面的代碼,直接到程序開頭的判斷部分,看要不要繼續往下執行代碼,示例如下:

//代碼多余的部分略
while (i <= 10)
{
  if(i == 5)
      continue;
  printf("%d ",i);
  i++;
}

上面的代碼打印結果就是 1234,然后后面就不打了

因為當i變為5的時候經 if 語句的判斷為真,到continue處,又回到代碼while循環判斷的開頭,看是否執行下一次的循環,判斷之后可執行,又經if 來到continue處,又回到while處判斷,可執行…如此往復下去,沒有跳出這個死循環的可能。后面也不可能再去打印別的東西。

for循環的continue,是直接跳到for循環的表達式3之中,執行調整部分,由此可見while循環和for循環的continue是有一定區別的,while循環是完全有可能直接跳過調整部分的,因為調整部分有可能在他的下面的代碼

譬如上面的代碼塊就是這樣的。

 

- for循環語法結構

for(表達式1;表達式2;表達式3)
{
  循環語句;
}

for循環其實是while循環的進一步改進,因為while循環的初始化部分(int i = 0),條件判斷部分(while(i>10)),調整部分(i ++),這幾個部分之間相隔有的時候會很遠,如果需要改動的話就會很容易改動。

for循環中,表達式1用于給循環變量一個初始值(表達式 1,只會執行一次,往后就沒用了,每次循環開始前變量保留著上一次的值,除非這個循環本身就在另一個循環之中,這樣的話每次都會初始化一遍,所以一般情況下,再上來的時候循環變量只會走 表達式 2 判斷一下和 表達式 3 自增一下,隨后繼續去執行下面的代碼),表達式2用于判斷,表達式3用于調整。

要注意的要點:盡量不要在循環體內改變循環變量,不然循環很容易失去控制,以下圖代碼塊為例:

#include <stdio.h>
int main()
{
  for(i=0; i<11; i++)
  {
      printf("%d",i);
      i = 5;
  }
  return 0;
}

上述代碼是一個連續打印6的一個死循環,因為每次走到第七行時,i 都會被賦值成 5。再上去到調整語句自增。

所以說循環內部千萬不要改變循環變量。

其次要注意的要點:for循環的語句判斷部分采用開區間,因為使用開區間的話不等號旁邊表示的是循環的次數

代碼的可讀性更高。比如:i<11.

for循環的用法也是非常靈活的,三個表達式可以隨意省略,但是判斷表達式還是最好不要省略,因為極易造成死循環。下面再來看一個示例:

#include <stdio.h>
int main()
{
  int i = 0;
  int j = 0;
  for(; i<3;i++)
      for(; j<3; j++)
      {
          printf("hehe\n");
      }
  return 0;
}

此處按照正常的理解來說,第四五行應該已經對 i 和 j 進行了初始化,隨后再去執行的時候,循環出三個 i ,每個 i 再分出來三個 j,所以總共應該打印應該是九個hehe。但事實上并不是這樣,真正的執行的過程為:i 初始化為 0之后,i 加一,與 j 相關的循環執行三次,printf 也打印三次,但是之后 i 在加一次,在執行 j 循環時,j 的初始化是在循環之外的,因此 j 仍然是3,循環無法執行,在往后也一樣是這樣。所以最終只打印三次hehe。

for循環還可以使用兩個變量循環變量來控制,例子如下:

int x ,y;
for(x = 0&&y = 0;x<10&&y<10;x++&&y++)

 

- do while循環

do
{
  語句1;
  語句2;
  .......
}while(判斷語句);
//判斷語句旁邊的的分號千萬不能少,不然的話語法就過不去了

do while循環執行方式很簡單,就是什么都不管直接先去執行括號內的語句,執行完了再去判斷還要不要繼續走下去,所以說do while 最少都能執行一次

do while 語句中的 continue 與 break 的用法

continue:直接跳過它下面的語句至最后的那個判斷語句,然后再從頭開始

break:直接就是調出所在的那個循環不執行了

示例:

do
{
  if(i == 5)
      continue;
  printf("%d ",i);
  i++;
}while(i<=10);

最終打印結果就是: 1234,因為當代碼中 i 走到 5 的時候,第5 行的continue 就會開始執行,使其跳轉到第8 行進行判斷,判斷為真,跳到開頭的第4行,繼續執行,再繼續跳轉…所以從 i 變成 5 開始,這段代碼就變成了死循環。

此外,如果第 5 行的語句被改成了 break 就會直接跳出所在的循環,直接去執行第 9 行的語句

 

循環練習題

- 題目一(階乘)

//計算n的階乘
#include <stdio.h>
int main()
{
  int ret = 1;
  int i = 0;
  int n = 0;
  scanf("%d",&n);
  for(i = 1; i<=n; i++)
  {
      ret *= i;
  }
  printf("%d",ret);
  return 0;
}

- 題目二(階乘和)

//計算 1!+2!+3!+.....+10!
//只寫出了核心步驟
  int ret = 1;
  int i,sum = 0;
  int n = 1;
  for(n=1; n<11; n++)
  {
      ret = 1;
//ret每次都必須要重新賦值
//不然里面會保留上一次的階乘值
//致使我們無法形成階乘相加的效果
      for(i = 1; i<=n; i++)
//注意,這里的 i ,每次都會初始化一次
//因為這個i的循環本身,就是在循環里面            
      {
          ret *= i;
      }
      sum += ret;
  }
  return 0;

上面這段代碼寫出來,思路非常的加單粗暴,就是要有各個不同的階乘,那么就用 n 來控制,要有階乘,那么就用 i 來控制。但是這種思路用來解決階乘相加的問題其實效率過低,因為每次當代碼走到第14行的時候 ,每次要算階乘的時候總是會出現一個問題,就是每一次階乘前面總是會把上一次的階乘重算一遍,再乘上一個最新更新的 i ,這樣非常浪費時間

圖解上面這段代碼的缺陷:

C語言基礎解析之分支與循環語句

所以說我們可以這樣想,可不可以更高效地利用數據,比如:1! 用完不要扔掉,再給他乘以一個 2,

變成 2!,同理 2!也不要扔掉,再給他乘以一個 3,最后把他們相加放到 sum 里面就行了。

//計算 1!+2!+3!+......+10!
//優化后的核心步驟
for(n=1; n<11; n++)
{
 ret *= n;
 sum += ret;
}

優化后的圖解:

C語言基礎解析之分支與循環語句

可以對照其對應的代碼塊,不難發現,這個效果一個循環就搞定了,利用率還非常高

- 題目三(二分查找)

//在一個有序數組中查找具體的某個數
//有序,即排好序的,如果從前往后找的話效率過低
//此題使用二分查找法
#include <stdio.h>
int main()
{
  int arr[10] = {1,2,3,4,5,6,7,8,9,10};
  int k = 7;//此處為要查找的元素
  int sz = size of(arr)/size of(arr[0]);
  //上面這行是用來計算出數組里面的元素個數
  int left = 0;
  int right = sz - 1;
  while(left <= right)
  {
      int mid = (left + right)/2;
      if(arr[mid] < k)
      {
          left = mid + 1;
      }
      else if(arr[mid] > k)
      {
          right = mid - 1;
      }
      else
      {
          printf("找到了,下標為:%d\n",mid);
          break;
      }
  }
  if(left > right)
  {
      printf("找不到\n");
  }
  return 0;
}

使用二分查找法去尋找數可以大大提高查找效率,其原理非常簡單:就是先算出數組中的元素個數,然后將查找時移動的右下標(right)初始值表示出來(即:數組元素個數減一),其次左下標(left)的初始值賦 0 (因為數組元素下標是從 0 開始的),然后表示出 mid ,就是左右下標的平均值,再用這個平均值去和要去查找的數 k 去比較,如果 mid 比 k 大,mid減一并將值賦給left,實現左值的更新,若 mid 比 k 小,mid 減一賦給 right,實現右值的更新,由此不斷循環往復左右值相距越來越近,若能實現左右值相等,則查找的數是存在的,若逼近到最后直至左右值交叉,則說明要查找的數不存在。圖示如下:

  • [

C語言基礎解析之分支與循環語句

https://imgtu.com/i/gm5KGF

- 題目四(兩邊往中間漸變)

//編寫多個字符從兩端向中間移動
//其實就是一串字符從兩端向中間移動
//每次露出左數第一個未知和右數第一個未知
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main()
{
  char arr1[] = "welcome to world";
  char arr2[] = "################";
  int left = 0;
  int right = strlen (arr1)-1;
  printf("%s\n", arr2);
  while(left <= right)
  {
      arr2[left] = arr1[left];
      arr2[right] = arr1[right];
      Sleep(1000);//此處s必須大寫,這里起到休眠1秒的作用
      system("cls");//此處起到閃屏的動態作用
      left++;
      right++;
      printf("%s",arr2);
  }
  return 0;
}

這道題目的原理和二分查找法類似,不再贅述。

此外還要注意的是:strlen()用于求字符串的長度,即里面含有幾個字符

sizeof()用于求數組所占的內存空間的大小

- 題目五(密碼登錄)

//模擬密碼登錄的情景,只允許登錄三次
//三次都不對,則退出程序
#include <stdio.h>
#include <string.h>
int main()
{
	int i = 0;
	char password[20] = { 0 };
	for (i = 0; i < 3; i++)
	{
		printf("請輸入密碼:> ");
		scanf("%s", password);//數組名本身就是地址,不是需要再用取地址符
		if (strcmp(password, "123456") == 0)//if后別加分號!!(淦,找了一個下午的bug)
		{
			printf("登陸成功\n");
			break;
		}
		else
		{
			printf("登陸失敗,請重新輸入!\n");
		}
	}
	if (i == 3)
	{
		printf("三次錯誤,退出程序\n");
	}
	return 0;
}

此處的 strcmp(字符串 1,字符串 2)是用于對比字符串的內容是否一致,如果一致,strcmp 返回一個 0 ,這也是為什么 if 里面判斷其是否等于 0。如果不一致,有兩種情況:字符串 1 大于字符串 2 ,返回值大于 0 ;字符串 1 小于字符串 2,返回值小于 0 。此外,strcmp 的比較方法是:字符串上的每一位逐個比較,比較對應位置上字符的 ASCII 碼值,不是比較字符串的長度,一旦對應位置上的字符大小分出高下,那么兩個字符也立刻分出高下,不管后面的字符或大或小或長或短。下面用圖示來解釋:

C語言基礎解析之分支與循環語句

- 題目六(猜數字游戲)

//寫一個猜數字游戲
//游戲要求如下:
//1.自動產生一個 1-100 之間的隨機數
//2.猜數字
//  a.猜對了,就恭喜你游戲結束
//  b.你猜錯了,會告訴你猜大了,還是猜小了
//3.游戲會一直玩,除非退出游戲
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()//menu函數的功能就是去實現一個菜單界面
{
	printf("-------------------\n");
	printf("-----1.玩游戲------\n");
	printf("-----2,退出游戲----\n");
	printf("-------------------\n");
}
void game()//game函數的功能就是去實現游戲的基本操作和隨機數的產生
{
	int ret = 0;
	int guess = 0;
	ret = rand() % 100 + 1;//此處就是生成隨機數的關鍵,rand的用法可以去MSDN去查
	                       //還有題目要求是1-100的隨機數所以rand返回值必須模上100.隨機數就可以被限定在0-99再加1,就是1-100
	while (1)//這個while實現的就是猜數字的的過程
	{
		printf("請猜一個數:> \n");
		scanf("%d", &guess);
		if (guess < ret)//這里就是要讓guess這個猜的值和我們隨機生成的數來做比較
		{
			printf("猜小了\n");
		}
		else if(guess > ret )
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜你,猜對了\n");
			break;
		}
	}
}
int main()
{
	srand((unsigned int)time(NULL));//這里和上面的rand相聯系,是rand語法規定的一部分,這里的作用來給生成的隨機數一個起點
	                                //里面的那個time()是個時間戳,就是用現在的時間和計算機的起始時間換算出一個隨機數
	                                //因為srand里面必須要填上一個隨機數所以用時間就是再好不過的了
	                                //還有就是srand的語法規定里面的數必須是無符號整形所以(unsigned int)用來強制改變數的類型
	int input = 0;
	do //此處使用do while循環就是要保證不管玩不玩先進去選擇
	{
	    menu();
		printf("請按菜單要求輸入一個數:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戲\n");
			break;
		defult ://此處的的defult 的作用也很關鍵。它可以防止玩家輸入其他數字進入到while()的判斷之中被誤判為真
			printf("輸入錯誤,請重輸\n");
		}
	} while (input);//此處用input來判斷是很巧妙的,因為選擇上input的只有0和1去供你選擇,若為0便是假 跳出循環 
	system("pause");      //若為 1便是真,繼續循環
	//選擇 0 的時候程序便會跳到67行終止
	return 0;
}

 

- goto語句

goto語句在C語言可以改變程序的進程順序,只要在想跳轉的地方做個標記,然后程序走到對應的goto語句處就會跳轉到標記處重新開始執行。(感覺有點像《火影忍者》里面波風水門的飛雷神)但是寫程序的時候要小心,goto語句有可能導致程序混亂產生bug。另外,goto語句不可以跨函數跳躍。

#include <stdio.h>
int main()
{
flag://這里就是標記的地方,一開始程序進去忽略這個東西
  printf("hehe\n");
  printf("haha\n");
  goto flag;//這里就是讓程序跳轉到標記處的語句
  return 0;
}

 

- getchar與putchar用法

下圖為示例:

#include<stdio.h>
int main()
{
  int ch = getchar();
  //getchar是用來接收鍵盤上輸入的字符
  //之后將接受的字符轉化為ASCII碼值存放起來
  //由前面的存儲類型是int也是可以看出來的
  //總之,用法是和scanf是差不多的
  putchar(ch);
  //putchar把接收到的字符打印出來
  //原理和printf差不多
  return 0;
}

此外還要注意的是:getchar獲取一個字符如果失敗了,那么他就會返回一個EOF

EOF 翻譯過來就是:文件終止(end of file)

#include <stdio.h>
int main()
{
  int ch = 0;
  while((ch = getchar())!=EOF)
  //上面條代碼就是讓getchar讀取一個數
  //判斷它有沒有讀取錯誤,若對的話則循環
  {
      putchr(ch);
  }
  return 0;
}

上面的這段代碼的效果即輸入什么就打印什么,可以不停地輸,不停地打

例:輸 a 則打 a,輸 b 則打 b。

如果想要循環停止的話,那么就可以輸入一個:ctrl 加 z ,其原理其實就是給 getchar 輸入一個錯誤字符

讓他終止,返回一個 EOF。

getchar 接收字符的原理:getchar 和 電腦鍵盤之間有一個緩沖區,該緩沖區用于存放鍵盤上輸入的東西,此外getchar 只要是緩沖區里面的東西一律照收不誤,包括回車,回車如果輸入進去就會被緩沖區理解為一個 \n ,所以上述代碼的輸入和打印形式為:

a //這里先給他一個a ,再打了一個回車

a

b

b

就是說,getchar 先讀取了 a ,隨后 a被打印,之后又讀取一個 \n 由此 b 只能在第三行開始輸入,以此類推…

getchar 與putchar的實際應用:

實例如下圖:

#include <stdio.h>
int main()
{
  int password[20] = {};
  printf("請輸入密碼:> ");
  scanf("%s", password);
  printf("請確認密碼:> ");
  int tmp = 0;
  while ((tmp = getchar()) != '\n')
  {
      ;
  }
  int ch = getchar();
  if (ch == 'Y')
  {
      printf("確認成功\n");
  }
  else
  {
      printf("確認失敗\n");
  }
  return 0;
}

上面的一段的代碼寫的是一個輸入密碼并確認的函數,具體分析:

首先我們創建一個數組,用于存放輸入的字符串,之后創建一個 tmp ,用循環來消耗 scanf 拿不走的字符串,就是讓while里面的getchar在讀到 \n 之前,一直用上面代碼塊中的第11行的空語句來來消耗那些沒用的(就是說getchar讀入,但不會進行操作),即空格剩下的 (空格)abcdef \n,因為如果不去消耗的話,第13行的getchar將直接讀取 6 后面的那個空格,然后自動默認走else 后面的分支,隨后在屏幕上直接打印 :確認失敗。由此可見,getchar 的作用非常直白,只是在讀取的時候看到緩沖區有什么就讀什么。

[

C語言基礎解析之分支與循環語句

到此這篇關于C語言基礎解析之分支與循環語句的文章就介紹到這了,更多相關C語言 分支與循環語句內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/qq_54693675/article/details/116422278

延伸 · 閱讀

精彩推薦
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
主站蜘蛛池模板: 青青草精品在线 | 99久久精品自在自看国产 | 精品视频 九九九 | 亲爱的客栈第二季免费观看完整版 | 日本在线视频免费看 | 五月天精品视频播放在线观看 | 国产成人精品视频一区 | 免费黄色网站视频 | 羞羞视频麻豆 | 免费一区二区视频 | 色哟约 | 金莲你下面好紧夹得我好爽 | 亚洲国产精品久久网午夜小说 | 嫩草视频在线观看免费 | 5g影院天天影院天天爽影院网站 | 国内自拍网红在线综合 | 精品国产自在现线久久 | 动漫女性扒开尿口羞羞漫画 | 91夜夜人人揉人人捏人人添 | 色橹橹 | 二区三区视频 | 特黄特级高清免费视频毛片 | 日韩亚洲一区中文字幕在线 | 男男同志videos | 韩国美女被的免费视频 | 亚州人成网在线播放 | 1024免费福利永久观看网站 | 国产免费资源高清小视频在线观看 | 欧美亚洲国产一区二区三区 | 亚洲AV久久无码精品蜜桃 | 91香蕉视频在线观看 | 精品小视频在线 | 成年人黄色录像 | 小sao货水好多真紧h的视频 | 国产成人99精品免费观看 | 亚洲国产日韩欧美一区二区三区 | 福利一区在线观看 | 国自产在线精品免费 | 日韩精品在线一区二区 | 天天乐影院 | 亚洲欧美一级夜夜爽w |