C语言小白进阶之路

  • 一、认识C语言基本语句(print()语句;scanf()语句)

首先,我们先来记住一个框架,不用理解,先记住

#include<stdio.h>

int main()

{

return 0;

}

接下来我们来打印第一个C语言程序

#include<stdio.h>
int main()
{
printf("Hello,word!\n");
return 0;
}

这里我们就用到了printf语句即标准化输出语句,用来打印我们要输出的东西

  • 程序中的main函数也叫主函数——程序的入口,main函数有且只有一个

  • 定义变量时

int a , b , c ; 或者写成

int a ;

int b ;

int c ;

了解一些C语言基本数据类型

  • short //短整形 字符串 %s

  • int //整形 %d

  • long //长整形

  • long long //更长的整形

  • char //字符数据类型 %c

  • float //单精度浮点数 %f

  • double //双精度浮点数 %lf

用printf语句输出int、float、double、char型数据

1、

#include<stdio.h>
int main()
{
    int a = 5, b, c, d, e, f;
    b = a + 2;
    c = b - a;
    d = a * c;
    e = a / d;
    f = a % d;
    printf("a=%d,b=%d,c=%d,e=%d,f=%d\n", a, b, c,e,f);
    
    return 0;
}

printf(" %d might %d is %d \n", a , b , c ); 转换说明的数量要与待打印值的数量相等

%取余 /取整?

2、

#include<stdio.h>
int main()
{
    double a, b, c, sum;
    a = 3.67;
    b = 5.43;
    c = 6.21;
    sum = (a + b + c) / 3;
    printf("a=%lf,b=%lf,c=%lf\n", a, b, c);
    printf("sum=%lf\n",sum);
    return 0;
}

3、

#include<stdio.h>
int main()
{
    char a = 'B', b = 'O', c = 'Y';
    a = a + 32;
    b = b + 32;
    c = c + 32;
    printf("小写字母依次是%c%c%c\n", a, b, c);
    return 0;
}

4.

请编写程序将简言希的英文名“Jane”加密,加密规律是:用原来的字母后面第一个字母代替原来的字母。例如字母"A"后面第1个字母是"B",用"B"代替"A",以此类推。

请编写程序进行上面的加密过程,并用printf语句输出者4个字符。

#include<stdio.h>
int main()
{
    char c1 = 'J', c2 = 'a', c3 = 'n', c4 = 'e';
    c1 ++;//注释:还可写成c1+=1/c1=c1+1
    c2 ++;
    c3 ++;
    c4 ++;
    printf("加密后的英文名是%c%c%c%c", c1, c2, c3, c4);
    return 0;

拓展:在编写代码时人们常会加上注释,以便他人理解,有两种注释方式

  1. // 用于单行注释

  1. /*

~~~~~~

*/用于单行或多行注释

关于进制问题

a , 默认为10进制 ,10 ,20。

b,以0开头为8进制,045,021。 %o

c.,以0b开头为2进制,0b11101101。

d,以0x开头为16进制,0x21458adf。%x

用scanf语句输入int、float、double、char型

float型

float a,b;

scanf("%f,%f",&a,&b);

double型

double a,b;

scanf("%lf,%lf",&a,&b);

char型

char a,b;

scanf("%c,%c",&a,&b);

Switch语句

例某课成绩原为百分制,现要将其转成等级,规则是:90分以上为A,80-90分为B、70-79分为C、60-69分为D、60分以下为E。请编一程序,分数由键盘输入,输出等级。

#include<stdio.h>
int main()
{
    double fenshu;
    printf("请输入分数:");
    scanf_s("%lf", &fenshu);//注释在某些编译器里需写成scanf才能运行此为vs示范
    switch ((int)(fenshu / 10))
    {
    case 10:
    case 9:printf("该生等级为A\n"); break;
    case 8:printf("该生等级为B\n"); break;
    case 7:printf("该生等级为C\n"); break;
    case 6:printf("该生等级为D\n"); break;
    case 5:
    case 4:
    case 3:
    case 2:
    case 1:
    case 0:printf("该生等级为E\n"); break;
    default:printf("你特么的输出是成绩?!\n"); break;
    }
    return 0;
}

if语句

if(表达式)

{

...

}

else

{

...

}

写个代码来简单应用一下吧😄

输入一个整数,如果该属大于60,则输出”简美女”;如果该数不大于60,则输出“简大美女”。

#include<stdio.h>
int main()
{
    int a;
    scanf_s("%d", &a);
    if (a > 60)
    {
        printf("简美女\n");
    }
    else
    {
        printf("简大美女\n");
    }    
 return 0;
}
  1. 输入两个实数a,b,按数值从小到大的顺序输出这两个数。

#include<stdio.h>
int main()
{
    double a, b, t;
    scanf_s("%lf,%lf", &a, &b);     或者写成
    if (a > b)                       double a,b;
    {                                scanf("%lf%lf",&a,&b);       
        t = a;                       a>b?printf("%f,%f\n",a,b):printf("%f,%f\n",a,b);
        a = b;                        return 0;
        b = t;
    }
    printf("%f,%f\n", a, b);
 return 0;
}

if语句 {-1,x<0

有一函数y={ 0,x=0 请编写一个程序,输入一个整数x时,输出相应的y值

{ 1,x>0

#include<stdio.h>
int main() 
{
    int x,y;
    scanf("%d",&x);
    if(x<0)                        也可这样写if(X>=0)
    y=-1;                                     if(x>0)
    else                                      y=1;
    {                                         else
        if(x>0)                                y=0;
        y=1;                                 else
        else                                   y=-1;
        y=0;
    }
    printf("x=%d,y=%d\n",x,y);
    return 0;
}

表达式1?表达式2:表达式3

判断表达式1是否正确,若正确执行表达式2否则执行表达式3

看代码

输入一个字符,判断是否未大写字母,若是则将其转成小写字母,若不是,则不转换

#include<stdio.h>
int main()
{
    char ch;
    scanf("%c",&ch);
    ch=(ch>='A'&&ch<='Z')?(ch+32):ch;
    printf("%c\n",ch);
    return 0;
}

for 循环

for( ; ; )

{

printf("该循环会永远执行下去!\n");

}

可以用for循环打印一个九九乘法表,去试试吧!时间关系这就不写了😁

do while 循环

do

{

statement(s);

}while( condition );

打印1+2+3+...+100=

#include<stdio.h>
int main()
{
    int i=1;
    int sum =0;
    do{
        sum = sum + i;
        i++;
    }while (i <= 100);
    printf("sum = %d\n",sum);
    return 0;
    }

结果输出sum=5050

while循环

while(condition)

{

statement(s);

}

#include <stdio.h>
 
int main ()
{
   /* 局部变量定义 */
   int a = 10;

   /* while 循环执行 */
   while( a < 20 )
   {
      printf("a 的值: %d\n", a);
      a++;
   }
 
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

a 的值: 10

a 的值: 11

a 的值: 12

a 的值: 13

a 的值: 14

a 的值: 15

a 的值: 16

a 的值: 17

a 的值: 18

a 的值: 19

while循环, 先判断后循环

do while循环,先循环后判断

break; 直接结束本次循环

continue; 结束本次循环进入下个循环

嵌套循环:外部循环一次,内部循环一套

数组

数组的分类,一维数组 和 二维数组

二维数组 int a[ ][ ] 行 列 在定义二维数组时可以没有行数但必须有列数

一维数组的初始化

a.全部初始化

int a[5]={1,2,3,4,5};

代表的意思:a[0]=1;a[1]=2;a[3]=4;....

b.部分初始化

int a[5]={2,4,3};初始化赋值不够后面补0

a[0]=2;a[1]=4;a[2]=3;a[3]=0;a[4]=0;...

注意: 只能省略后面元素,可以不初始化,不能中间的不初始化

#include<stdio.h>
int main()
{
    int a[5]={1,2,3,4,5};
    int i;
    for(i=0;i<5;i++)
    {
        printf("a[%d]=%d\n",i,a[i]);
    }
    return 0;
    }
#include<stdio.h>
int main()
{
    int a[2][2]={ {1,2} , {4,5} };
    int i,j;
    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            printf("a[%d][%d]=%d ",i,j,a[i][j]);
        }
        printf("\n");
    }
    return 0;
    }

字符数组

char c1[] = { 'c', ' ', 'p', 'r','o', 'g' };

char c2[] = "c prog";

char a[][6] = { "hello" , "word" };

字符数组的引用

  1. 用字符串方式赋值比用字符逐个赋值要多占1个字节,用于存放字符串结束标志'\0' ;

  1. 上面的数组c2在内存中的实际存放情况为:

' c '

' '

' p '

' r '

' o '

' g '

' \0 '

注:'\0'是由C编译系统自动加上去的

sizeof可求数组所占的字节数

#include<stdio.h>
int main()
{
   char  c1[] = { 'c',' ','p','r','o','n','g'};
   char  c2[] = "c prong";
   printf("sizeof(c1)=%d\n",sizeof(c1));
   printf("sizeof(c2)=%d\n",sizeof(c2));
   printf("%s\n",c2);
   return 0;
    }

#include<stdio.h>
int main()
{
   char str[15];
   printf("please input a str :\n");
   scanf("%s",str,15);//这里数组名是地址,不用加取地址符 & 
   printf("str:%s\n",str);
   return 0;
    }

学完了数组来看两道题吧

  1. 求年月日

  1. 打字游戏

函数

函数的概念:函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。

函数的分类

  1. 从定义角度分类(即函数是谁实现的)

1.库函数(c库实现的)

2.自定义函数(程序员自己实现的函数)

3.系统调用(操作系统实现的函数)

  1. 从参数角度分类

1.有参函数

函数又形参,可以是一个,或者多个,参数的类型随便完全取决于函数的功能

int fun(int a,float b,double c)——>形参

{

}

int max(int x,int y)

{

}

2.无参函数

函数没有参数,在形参列表的位置写个void或什么都不写

int fun(void)

{

}

int fun()

{

}

  1. 从返回值角度分类

(1)带返回值的函数

在定义函数的时候,必须带着返回值类型,在函数体里,必须有return如果没有返回值类 型, 默认返回整型。

char fun()//定义了一个返回字符数据的函数

{

char b='a';

return b;

}

(2)没返回值的函数

在定义函数的时候,函数名字前面加void

void fun(形参表)

{

;

;

return;

;

}

在函数里不需要return

如果想结束函数,返回到被调用的地方,return;什么都不返回就可以了

定义函数

C 语言中的函数定义的一般形式如下:

return_type function_name( parameter list )

{

body of the function

}

#include<stdio.h>
int max( int x,int y)
{
    int z;
    if(x>y)
    {
        z=x;
    }
    else
    {
        z=y;
    }
    return z;
 } 
 void help(void)
 {
    printf("*********************\n");
    printf("打印帮助信息\n");
    printf("*********************\n");
 }
 int main()
 {
     int num;
     num = max(5,10);
     printf("num =%d\n",num);
     num =max(11,22);
     printf("num=%d\n",num);
     help();
     return 0;
 }

注:在一个程序中,函数只能定义一次

给函数起名时,尽量见名之意,符合c语言命名规则

函数的声明:

对已经定义的函数,进行说明,函数的声明可以声明多次。

#include<stdio.h>
void fun (void)//被调函数在上,主调函数在下,不需要声明
{
   printf("hello word!\n");
}
int main()
{
    fun();
   return 0;
}
#include<stdio.h>
void fun (void);//直接声明法:将被调用的函数的第一行拷贝过去,后面加分号
int main()
{
    fun();
   return 0;
}
void fun(void)
{
   printf("hello word!\n");
}

define

定义宏用define去定义

宏是在预编译的时候进行替换

  1. 不带参宏

#define PI 3.14

在预编译的时候如果代码中出现了PI就用3.14去替换

宏的好处:只要修改宏定义,其他地方在预编译的时候就会重新替换。

注意:宏定义后边不要加分号。

宏定义的作用范围,从定义的地方到本文件的末尾。

如果想在中间终止宏的定义范围

#undef PI//终止PI的作用

2.带参宏

#define S(a,b) a*b

注意带参宏的形参a和b没有类型名,

S(2,4)将来在预处理的时候替换成实参替代字符串的形参,其他字符保留,2*4,就是把S(2,4)变成了2*4

指针

指针的概念:

指针也就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。

指针变量的定义:

数据类型 * 指针变量名

int * p;//定义了一个指针变量p

指针变量声明的一般形式为:

type *var_name;

在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var_name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:

int *ip; /* 一个整型的指针 */

double *dp; /* 一个 double 型的指针 */ (指针的分类,此外还要长整型、函数、结构体指针)

float *fp; /* 一个浮点型的指针 */ 数组指针、指针的指针、通用指针 void*

char *ch; /* 一个字符型的指针 */

在32位系统下任何类型的指针变量都是4个字节大小 64位是8个字节

指针只能存放对应类型的变量的地址编号

关于指针的运算符

& 取地址 、 * 取值

例1:

int a=0x1234abcd;

int *p;//在定义指针变量的时候*代表修饰的意思,修饰p是个指针变量。

p=&a;//把a的地址给p赋值,&是取地址符

p保存了a地地址,也可以说p指向了a

int num;

num=*p

分析:

1.在调用的时候,*代表取值的意思,*p就相当于p指向的变量,即a,

2.故num=*p 和 num=a 的效果是一样的。

  1. 所以说num 的值为0x1234abcd。

#include<stdio.h>
int main()
{
    int a = 100, b = 200;
    int* p_1, * p_2 = &b;
    p_1 = &a;
    printf("a=%d\n", a);
    printf("*p_1=%d\n", *p_1);
    printf("b=%d\n", b);
    printf("*p_2=%d\n", *p_2);
    return 0;
}

指针和变量的关系

打印程序实现a 和b的值调换

#include<stdio.h>
int main()
{
    int* p1, * p2, temp, a, b;
    p1 = &a;
    p2 = &b;
    printf("请输入 a 和 b 的值\n");
    scanf_s("%d %d", p1, p2);
    temp = *p1;
    *p1 = *p2;
    *p2 = temp;
    printf("a =%d b=%d\n", a, b);
    printf("*p1 =%d *p2=%d \n", *p1, *p2);
    return 0;
}

指针和数组元素的关系

数组元素的引用方法

方法1:数组名[下标]

int a[5];

a[2]=100;

方法2:指针名加下标

int a[5];

int *p;

p=a;

p[2]=100;//因为p和a等价

补充:C语言规定:数组的名字就是数组的首地址,即第0个元素的地址,是个常量。

注意:p和a的不同,p是指针变量,而a是个常量。可用等号给p赋值,但不能给a赋值

p=&a[3];//正确

a=&a[3];//错误

方法3:通过指针变量运算加取值的方法来引用数组的元素

int a[10];

int *p;

p=a;

*(p+2)=100;//也是可以的,相当于a[2]=100

解释:p是第0个元素的地址,p+2是a[2]这个元素的地址。

对第2个元素的地址取值,即a[2]

方法4:通过数组名+取值的方法引用数组的元素

int a[10];

*(a+2)=100;//也是可以的,相当于a[2]=100;

注意:a+2是a[2]的地址。这个地方并没有给a赋值。

通过代码来熟悉一下吧(vs里*86是32位系统,*64是64 位系统)

#include<stdio.h>
int main()
{
    int a[5] = { 0,1,2,3,4 };
    int* p;
    p = a;
    printf("a[2]=%d\n", a[2]);
    printf("p[2]=%d\n", p[2]);
    printf("*(p+2)=%d\n", *(p + 2));
    printf("*(a+2)=%d\n", *(a + 2));
    printf("p=%p\n", p);
    printf("p+2=%p\n", p + 2);
    return 0;
}

指针的运算

1、指针可以加一个整数,往下指向几个它指向的变量,结果还是个地址

2、两个相同类型指针可以比较大小

3、两个相同类型的指针可以做减法

4、两个相同类型的指针可以相互赋值

指针数组

1.指针数组的概念:指针数组本身是个数组,是个指针数组,数组中有若干个相同类型指针变量,这个数组被称为指针数组

2.指针数组的定义方法

类型说明符 * 数组名 [元素个数];

int *p[5];//定义了一个整型的指针数组p,有5个元素p[0]~p[5],

每个元素都是int*类型的变量

int a;

p[0]=&a;

int b[10];

p[1]=&b[5];

#include<stdio.h>
int main()
{
    int* p[5];
    int a = 100;
    int b[10] = { 1,2,3,4,5,6,7,8,9,0 };
    printf("sizeof(p)=%d\n", sizeof(p));
    p[0] = &a;
    printf("p[0]=%p\n", p[0]);
    printf("&a=%p\n", &a);
    printf("*p[0]=%d\n", *p[0]);
    p[1]= &b[2];
    printf("*p[1]=%d\n", *p[1]);
    return 0;
}
#include<stdio.h>
int main(int argc, const char* argv[])
{
        const char* name[5] = { "hello","China","beijing","project","Computer" };
        int i;
        for (i = 0; i < 5; i++)
        {
            printf("%s\n", name[i]);
        }
        return 0;
}

指针的指针

int a=0x12345678;

假如:a的地址是 0x00002000

int *p;

p=&a;

则p中存放的是a的地址编号即 0x00002000

因为p也占4个自己内存,也有它自己的地址编号,及指针变量的地址,即指针的指针。

假如:指针变量p的地址编号是0x00003000,这个地址编号就是指针的地址

我们定义一个变量存放p的地址编号,这个变量就是指针的指针

int **q;

q=&p;//q保存了p的地址,也可以说q指向了p

则q里存放的就是0x00003000

#include<stdio.h>
int main(int argc,  char* argv[])
{
    int a = 0x12345678;
    int* p;
    int** q;
    int*** m;
    p = &a;
    printf("&a=%p\n", &a);
    printf("p=%p\n", p);
    q = &p;
    printf("&p=%p\n", &p);
    printf("q=%p\n", q);
    m = &q;
    printf("&q=%p\n", &q);
    printf("m=%p\n", m);

    printf("*p=%x\n", *p);
    printf("**q=%x\n", **q);
    printf("***m=%x\n", ***m);
        return 0;
}

字符串的概念及其存储形式

字符串的概念

字符串就是以'\0'结尾的若干个字符的集合,比如”helloword“。

字符串的地址,是第一个字符的地址。如:字符串”helloword"的地址,其实是字符串中字符'h'的地址。我们可以定义一个字符指针变量保存字符串的地址,比如: char *s="helloword";

字符串的存储形式:数组、文字常量区、堆

1,字符串存放在数组中

char string[100]="I love C!"

2.文字常量区

char *str="I love C!"

3.堆区

char *str=(char*)malloc(10);动态申请了10个字节的存储空间

字符串的可修改性:存放在数组和堆中可修改,文字常量中不可修改(注数组没有被const修饰

初始化:

1.字符数组初始化:

char*buf_aver[20]="hello world";

2.指针指向文字常量区,初始化:

char*buf_point="hello world";

3、指针指向堆区,堆区存放字符串。

不能初始化,只能先给指针赋值,让指针指向堆区,再使用strcpy、scanf等方法把字符串拷贝到堆区。char*buf_heap;

buf_heap=(char*)malloc(15);

strcpy(buf_heap,"helloworld");

scanf(“%s”,buf_heap);

使用时赋值

  1. 字符数组:使用scanf或者strcpy

charbuf[20]=”hello world”

buf="hello kitty"; 错误,因为字符数组的名字是个常量,不能用等号给常量赋值。strcpy(buf,"hello kitty"); 正确,数组中的内容是可以修改的

scanf("%s",buf); 正确,数组中的内容是可以修改的

2.指针指向文字常量区

char*buf_point=“hello world”;

1)buf_point="hello kitty"; 正确,buf_point指向另一个字符串

2)strcpy(buf_point,"hello kitty"); 错误,这种情况,buf_point指向的是文字常量区,内容只读。

当指针指向文字常量区的时候,不能通过指针修改文字常量区的内容。

3.指针指向堆区,堆区存放字符串

char*buf_heap;buf_heap=(char*)malloc(15);

strcpy(buf_heap,"helloworld");

scanf(“%s”,buf_heap);

字符串和指针总结:

1、指针可以指向文字常量区

1)指针指向的文字常量区的内容不可以修改

2)指针的指向可以改变,即可以给指针变量重新赋值,指针变量指向别的地方。

2、指针可以指向堆区

1)指针指向的堆区的内容可以修改。

2)指针的指向可以改变,即可以给指针变量重新赋值,指针变量指向别的地方。

3、指针也可以指向数组(非const修饰)

例:charbuf[20]="hello world";

char*str=buf;

这种情况下

1.可以修改buf数组的内容。

2.可以通过str修改str指向的内存的内容,即数组buf的内容

3.不能给buf赋值buf=“hello kitty”;错误的。

4.可以给str赋值,及str指向别处。str=“hello kitty”

数组指针

1、二维数组

二维数组,有行,有列。二维数组可以看成有多个一维数组构成的,是多个一维数组的集合,可以认为二维数组的每一个元素是一个一维数组。

例:

int a[3][5];

定义了一个3行5列的一维数组。

可以认为二维数组a由3个一维数组构成,每个元素是一个一维数组。

回顾:

数组的名字是数组的首地址,是第0个元素的地址,是个常量,数组名字加1指向下个元素

二维数组a中,a+1指向下个元素,即下一个一维数组,即下一行。

2.数组指针的概念:

本身是个指针,指向一个数组,加1跳一个数组,即指向下个数组。

3.数组指针的定义方法:

指向的数组的类型(*指针变量名)[ 指向的数组的元素的个数]

int (*p)[5];// 定义了一个数组指针变量p,p指向的是整型的有5个元素的数组

p+1往下指5个整型,跳过一个有5个整型元素的数组

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简而言之希

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值