C/C++(语句,数组)

C语言语句:

两大选择,三大循环,四大跳转

两大跳转:if,switch
三大循环:for,while,do-while
四大跳转:break,continue,goto,return

do-while直到型循环,用作参数型检查,直到你输入的数据符合条件为止。

#include<stdio.h>
int main() {
    int name;
    int paswd;
    do{
        printf("请输入用户名!");
        scanf("%d",&name);
        printf("请输入密码!");
        scanf("%d",&paswd);
    }while(!(name == 10 && paswd == 20));
    printf("欢迎光临!");
}

return退出当前函数,在main函数中return比较特别结束程序。

for(int i = 0;i < 5;i++) {
    for(int j = 0;j < 5;j++) {
        for(int k =0; k < 5;k++) {
            if(k == 3) {
                break;//只能跳出一层循环,一层循环
                continue;//一层循环
                return 0;//跳出正割函数
                goto end;//用于处理跳出多层循环。常用于集中式的错误处理。
            }
            printf("k层循环");
        }
        printf("j层循环");
    }
    printf("i层循环");
end:
}

数组

相同的数据类型进行构造就是数组,不同的数据类型构造就是结构体。
构造类型研究的方法:定义,初始化,访问

#include<stdio.h>
int main() {
    int arr[10];//理解为int[10] arr
    printf("sizeof(arr) = %d
",sizeof(arr));//40
}

数组初始化:

//未初始化,全部清零
int arr[10];
//满初始化
int arr[5] = {1,2,3,4,5};
//部分初始化,其余部分清零
int arr[5] = {1,2,3};
//越界初始化,这种方式禁止,c语言对于越界不检,并不是错误,很灵活。
int arr[5] = {1,2,3,4,5,6,7,8};
//错误的赋值:
int arr[10];
arr[10] = {1,2,3,4,5,6,7,8,9,0};
//这两个左右代表的不是同一个概念,左侧arr[10],访问的是数组越界的元素,右边是一个数组。

//凡是构造类型,要么在定义时初始化,不可以先定义在初始化的方式赋值。
//凡是基本类型,即可一在定义时初始化,一可以先定义,再赋值。

//不定义大小初始化
int arr[] = {1,2,2,3,4,7,5,6};//根据数组大小自适应大小
for(int i = 0;i < sizeof(arr)/sizeof(int);i++) {
    printf("%d
",arr[i]);
}

一维数组的逻辑与存储

在内存中是一组连续的存储区域。
数组的三要素:
起始位置(数组名),移步刻度(类型),终止位置(范围-数组大小)

int arr[10];//arr 代表的是构造类型参与元素的访问,此时还代表首元素的地址。
printf("%d %d
",arr[1],1[arr]);//[]下标运算符,深层次上市基址变址运算符

//下表为什从零开始,因为从基址处偏移零个单位储存的是第一个元素

变长数组

从运行开始有一次改变大小的机会,在其后的运行期间不可以改变大小,val不可以初始化

int val = 100;
int arr[val];
//int arr[val] = {1,2,3,4};会报错
printf("sizeof(arr) = %d
",sizeof(arr));//400
var = 200;
printf("sizeof(arr) = %d
",sizeof(arr));//400并不是800

数组的数据形态

1.求平均值:

int arr[10];
int sum = 0;
for(int i = 0;i < 10;i++) {
    sum += arr[i];
}
printf("average is: %d/n",(float)sum/10);

2.最值问题:假设某一个成员(第一个成员为最值),然后依次比较。

int maxValue;
int minValue;
int arr[10] = {11,23,45,67,45,3,4,23,56,78};
maxValue = arr[0];
minValue = arr[0];
for(int i = 0;i < 10;i++) {
    if(arr[i] > maxValue) 
        maxValue = arr[i];
    if(arr[i] < minValue)
        minValue = arr[i];
}
printf("最大值为:%d 最小值为:%d",maxValue,minValue);

3.次最值
4.排序:
选择排序:选择第一个元素依次对后面的元素进行比较,确定一个最值,在选择第二个元素依次和后面的元素比较。

//选择排序
int arr[10] = {23,1,45,4,3,46,78,89,6,711};
for(int i = 0;i < 9;i++) {
    for(int j = i+1;j < 10;j++) {
        if(arr[i] > arr[j]) {
            tem = arr[i];
            arr[i] = arr[j];
            arr[j] = tem;
        }
    }
}
for(int i = 0;i < 10;i++) {
    printf("arr[%d]%d
",i,arr[i]);
}

比较的提升:比较不可少,减少交换。比而不换,记录下标,比较下表,下标不同交换。
基本思想:额外记录一个下标,第一次循环时,记录第一个下标index,判断第一个值与后面值得关系,如果第一个值大于后面的一个元素时,交换此下标值。依据此值比较一趟完毕后判断index是否与原来的下标值相等,不等说明arr[index]的值是要交换的。

int tem;
int arr[10];
for(int i = 0;i < 10;i++) {
    arr[i] = rand()%10;
}
for(int i = 0;i < 9;i++) {
    int index = i;
    for(int j = i+1;j < 10;j++) {
        if(arr[index] > arr[j]) {
            index = j;
        }
    }
    if(index != i) {
        //tem = arr[index];
        //arr[index] = arr[i];
        //arr[i] = tem;
        arr[index] ^= arr[i];
        arr[i] ^= arr[index];
        arr[index] ^=arr[i];
    }
}
for(int i = 0;i < 10;i++) {
    printf("arr[%d]=%d
",i,arr[i]);
}

线性查找

//查找一个数,数据存在,下标是多少。
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int findData = 5;
int index = -1;
for(int i = 0;i < 10;i++) {
    if(arr[i] == findData) {
        index = i;
    }
}
if(index == -1) 
    printf("不存在这个数!");
else
    printf("index=%d
",index);

折半查找:

前提是数组有序的。

int findData = 5;
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
int left = 0;
int right = 9;
int mid = -1;
while(left <= right) {
    mid = (left + right)/2;
    if(findData == arr[mid])
        break;
    else if(findData > arr[mid])
        left = mid + 1;
    else if(findData < arr[mid])
        right = mid - 1;
}
if(mid != -1) {
    printf("index=%d
",mid);
}else{
    printf("find none");
}

二维数组

研究对象:定义,大小,初始化,访问及三要素

定义及大小

//大小
int arr[3][4];
printf("sizeof(arr) = %d
",sizeof(arr));//(3*4)*4
printf("sizeof(arr[0]) = %d
",sizeof(arr[0]));//4*4

初始化及访问:

//满初始化
int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for(int i = 0;i < sizeof(arr)/sizeof(arr[4]);i++) {
    for(int j = 0;j < 4;j++) {
        printf("%3d",arr[i][j]);
    }
    putchar(10);
}
//部分初始化有两种:
int arr[3][4] = {1,2,3,4};//和一维数组相同,其余部分补0,呈线性分布
int arr[3][4] = {{1,2},{,3,4},{,4,5}};//其余部分补0
//大小自适应,只能省略行数
int [][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

三要素

(起始地址,步长,范围)

//一维数组
int arr[4];
printf("arr = %p
",arr);
printf("&arr[0] = %p
",&arr[0]);//起始地址

printf("arr = %p arr + 1 = %p
",arr,arr+1);//步长
for(int i = 0;i < 4;i++) {//范围不要越界
    printf("%d
",arr[i]);
}
//二维数组
//起始位置的研究
int arr[3][4];
printf("arr = %p
",arr);//起始地址
printf("&arr[0] = %p
",&arr[0]);//整体二维数组的起始地址

printf("arr[0] = %p
",arr[0]);//内嵌起始数组地址
printf("&arr[0][0] = %p
",&arr[0][0]);//内嵌数组第一个元素数组中的第一个数组元素的起始地址
//步长研究:
printf("arr = %p arr + 1
",arr,arr+1);//内嵌一维数组的步长(加16)
printf("arr[0] = %p arr[0] + 1
",arr[0],arr[0]+1);//内嵌一维数组的步长(加4)

//一维数组的数组名是一级指针,二维数组的数组名是数组指针

&:取地址符,引用(reference)
*:取内容,节引用(dereference)

int arr[3][4] = {{1,2,3,4},{5,6,7,8},{},{}};
printf("arr = %p
",arr);
printf("*arr = %p
",*arr);//两者的效果是一样的
printf("arr+1 = %p
",arr+1);//加16
printf("*arr+1 = %p
",*arr+1);//加4
//对二维数组名取节引用就是二维数组中内嵌的一维数组首元素地址
printf("%d
",*(*(arr+1)+2));
//*(arr+1),对arr=1,取节引用,相当于内层嵌套第二行首元素地址,+2,表示向后偏移两个内嵌元素的步长,*(*(arr+1)+2),再对其求节引用(取内容)相当于arr[1][2]。

数据形态

二维数组对角线的输出

//主对角线上的元素
int arr[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
for(int i = 0;i < 4;i++) {
    for(int j = 0;j < 4;j++) {
        if(i == j) {
            printf("主对角线上的元素为:%d
",arr[i][j]);
        }
    }
}
//副对角线上的元素
int arr[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
for(int i = 0;i < 4;i++) {
   printf("%d
",arr[i][3-i]);
}

二维数组的逆秩

char arr[4][4] = {'a','b','b','b','c','a','b','b','c','c','a','b','c','c','c','a'};
for(int i = 0;i < 4;i++) {
    for(int j = 0;j < 4;j++) {
        printf("%2c",arr[i][j]);
    }
    putchar(10);
}
char tem;
for(int i = 0;i < 4;i++) {
    for(int j =0;j < 4;j++) {
        if(i>j) {
            //printf("%2c",arr[i][j]);//下三角
            tem = arr[i][j];
            arr[i][j] = arr[j][i];
            arr[j][i] = tem;
        }
    }
    putchar(10);
}

//printf("++++++++++++++++++++++++
);
for(int i = 0;i < 4;i++) {
    for(int j = 0;j < 4;j++) {
        printf("%2c",arr[i][j]);
    }
    putchar(10);
}

天生棋局

生成一个10*10的棋局,要求,初始化为零。随机置入10颗棋子,棋子处置为1,并打印。

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int main() {
srand(time(NULL));
int chess[10][10] = {0};
int x,y;
int count = 0;
while(1) {
    x = rand()%10;
    y = rand()%10;
    if(chess[x][y] != 1) {
        chess[x][y] = 1;
        count++;
        if(count == 10) {
            break;
        }
    }
}

for(int i = 0;i < 10;i++) {
    for(int j = 0;j < 10;j++) {
        printf("%2d",chess[i][j]);
    }
    putchar(10);
}

}

若在棋中出现连续的三个旗子就称为好气。

srand(time(NULL));
int chess[10][10] = {0};
int x,y;
int count = 0;
while(1) {
    x = rand()%10;
    y = rand()%10;
    if(chess[x][y] != 1) {
        chess[x][y] = 1;
        count++;
        if(count == 10) {
            break;
        }
    }
}

for(int i = 0;i < 10;i++) {
    for(int j = 0;j < 10;j++) {
        printf("%2d",chess[i][j]);
    }
    putchar(10);
}
//行扫描
count = 0;
int flag = 0;
for(int i = 0;i < 10; i++) {
    for(int j = 0;j < 10;j++) {
        if(1 == chess[i][j]) {
            count++;
            if(count == 3) {
                flag = 1;
                break;
            }
        }else {
            count = 0;    
        }
    }
    if(flag == 1) {
        break;
    }
}
//列扫描
for(int i = 0;i < 10;i++) {
    count = 0;
    for(int j = 0;j < 10;j++) {
        if(1 == chess[j][i]) {//列行互换就能扫描的列
            count++;
            if(count == 3) {
                flag = 1;
                break;
            }
        }else {
            count = 0;
        }
    }
    if(flag == 1) {
        break;
    }
}
if(flag == 1) {
    printf("good chess!
");
}else {
    printf("bad chess!
");
}

有序数组的并归

#include<stdio.h>
#define M 5
#define N 3
int main() {
    int A[M] = {1,3,5,7,9};
    int B[N] = {2,4,6};
    int C[M+N];
    int i = 0,j = 0,k = 0;
    while(i < M && j <N) {
        if(A[i] < B[j]) {
            C[k++] = A[i++];
        }else {
            C[k++] = B[j++];
        }
    }
    if(j == 3) {//可以去掉判断
        while(i < 5) {
            C[k++] = A[i++];
        }
    }else{//可以去掉
        while(j < 3) {
            C[k++] = B[j++];
        }    
    }
    for(int i = 0;i < M+N;i++) {
        printf("%d
",C[i]);
    }
}

数组名的二义性

数组名是数组的唯一标识符

1.数组名充当一种构造类型
2.数组名充当访问数据成员的首地址

int arr[10] = {2};
printf("sizeof(arr) = %d
",sizeof(arr));
printf("sizeof(int[10]) = %d
",sizeof(int[10]));

printf("arr=%p
",arr);
printf("&arr=%p
",&arr);
printf("arr[0]=%p
",*(arr+0));

int arr[3][4] = {1,2,3};
prinf("sizeof(arr) = %d
",sizeof(arr));
prinf("sizeof(int [3][4]) = %d
",sizeof(int [3][4]));

prinf("arr %p
",arr);
prinf("&arr[0] = %p
",&arr[0]);

for(int i = 0;i < 3;i++) {
    for(int j = 0;j < 4;j++) {
        printf("%d",*(arr[i]+j));//线性的具体成员arr[i],是一维数组的数组名
    }
    putchar(10);
}
原文地址:https://www.cnblogs.com/intelwisd/p/8233017.html