第一个程序

输出: printf("") ""里是字符串,\n是换行
每一行代码都要有分号 隔几个格没有关系 再下一行没有别的语句就可以
做计算
#include<stdio.h>
int main()
{
printf("%d",12+34);
return 0;
}
这里的%d用法和python一样 都是把后面要输出的内容填到%d的位置上去
四则运算

基本数据类型
变量
算找零

变量定义
<类型名称><变量名称>;
int price
int prince,amount 是有两个变量,因为都是int所以放在一行里
标识符
变量的名字
规则:标识符只能由字母,数字,下划线组成;且数字不可以出现在第一个位置,关键字不可以用标识符

如何输入?
赋值和初始化
赋值int price=0
定义了一个变量,变量的名字是int,初始值是0;price=0是一个式子,'='是一个赋值运算,把右边的值交给左边
初始化 所有变量在第一次被使用之前应该被赋值一次;<类型名称><变量名称>=<初始值>
读整数
scanf("%d",&price);要求scanf读入下一个整数,读的结果赋值给变量price
找零代码
#include<stdio.h>
int main()
{
int price=0;
printf("请输入一个整数:");
scanf("%d",&price);
int change=100-price;
printf("找您%d元\n",change);
return 0;
}
变量输入
#include<stdio.h>
int main
{
int a=0;
int b=0;
scanf("%d %d",&a,&b);
printf("%d %d\n”,a,b);
return0;
}
只要是出现在scanf("%d %d",&a,&b)格式字符串里的所有东西都是要读的,读完之后交给后面的某一个变量
但如果scanf("%d,%d",&a,&b)若输入1 2,结果却是1 0。是因为输入形式与代码形式不统一,应该输入1,2所以说对字符串的输入要求十分严格,假如不小心在第二个%d后面多摁了一个空格,那么在操作台上输入a,b的值后,还要输入一个才能够进行下去(但其实你输入的这个数不会对结果有影响,因为不会被读进去
所以出现在scanf字符串中的是要你去输入的,要不然就会出错
常量vs变量
再找零钱的代码中 int change=100-price,100是常数是不变的量
,而price和change是变量
直接写在程序中的量称之为直接量
#include<stdio.h>
int main()
{
const int AMOUNT=100
int price=0;
printf("请输入一个整数:");
scanf("%d",&price);
int change=AMOUNT-price;
printf("找您%d元\n",change);
return 0;
}
const
是一个修饰符,放在int的前面,用来给这个变量加上一个不变的属性。这个const的属性表示这个变量的值一旦初始化,就不能再修改了
但是我们想让用户输入变量AMOUNT,而不是使用固定的初始值,把const删掉,改成变量
#include<stdio.h>
int main()
{
int amount=100;
int price=0;
printf("请输入一个整数:");
scanf("%d",&price);
printf("请输入票面:");
scanf("%d",&amount);
int change=amount-price;
printf("找您%d元\n",change);
return 0;
}
plus.c(输入输出格式例子
#include<stdio.h>
int main()
{
int a;
int b;
printf("请输入两个整数:");
scanf("%d %d",&a,&b);#%d之间用空格隔开,输入的时候两个数也要用空格隔开
printf("%d +%d =%d\n",a,b,a+b);
return 0;
}
浮点数
计算身高的程序
#include<stdio.h>
int main()
{
printf("请分别输入身高的英尺和英寸:");
int foot;
int inch;
scanf("%f %f",&foot,&inch);
printf("身高是%f米。\n",
((foot + inch /12.0)* 0.3048));#这里的12要改为12.0,因为前面是%f
return 0;
}
在生活中呢,我们默认10和10.0是一个数,但是在计算机的角度来看并不是一个数,10.0是浮点数
double
double是双精度浮点数,后面的数字就不用改成浮点数的形式了
#include<stdio.h>
int main()
{
printf("请分别输入身高的英尺和英寸:");
double foot;
double inch;
scanf("%lf %lf",&foot,&inch);
printf("身高是%lf米。\n",
((foot + inch /12)* 0.3048));#这里的12不用改为12.0,因为前面是double,但是是%lf
return 0;
}
表达式

计算时间差
输入两个时间,每个时间分别输入小时和分钟的值,然后输出两个是时间之间的差,也以几小时几分表示
#include<stdio.h>
int main()
{
int hour1,minute1;
int hour2,minute2;
scanf("%d %d",&hour1,&minute1);
scanf("%d %d",&hour2,&minute2);
int t1 = hour1*60+ mintue1;
int t2 = hour2*60+ mintue2;
int t =t2- t1;
printf("时间差是%d小时%d分钟。",t/60,t%60)
return 0;
}
运算符优先级
求平均数

注意赋值运算
a=b=6,运算顺序是自右向左,所以先算b=6,再算6=a
运算符
a = b + 5
a,b,5都是算子,+=是运算符
关系运算
-
==,!=,>=,<=,<,>
-
当两个值的关系符合关系运算符的预期时,关系运算的结果就为1,否则为0
-
printf("%d\n",5==3)
因为5不等于3,所以不满足关系运算符的预期,运行结果为0
-
所有的关系运算符的优先级比算术运算符的低,但是比赋值运算的高
算数运算符>关系运算符>赋值运算符
-
判断是否相等的优先级比其他的低
-
连续的运算关系时从左到右进行的
交换两个变量
int a=6; int b=5;
如何交换a,b的值
思路:假如有两杯子的水,你怎么交换呢,另取一个空杯子,那么变量交换也是如此,设设一个空值
#include<stdio.h>
int main()
{
int a=5;
int b=6;
t=a;
a=b;
b=t;
printf("a=%d,b=%d\n",a,b)
return 0;
}
若想看到a,b,t三个值交换的过程
调试
先设一个断点 然后点击下一步
练习2-1

#include <stdio.h>
int main()
{
int cm=0;
scanf("%d",&cm);
int foot=cm/30.48;
int inch=((cm/30.48)-foot)*12;
printf("%d %d",foot,inch)
return 0;
}
题中给的是求厘米cm的式子,但输出要求是英尺和英寸,所以需要转换一下
选择结构
if语句做判断
if(成立条件){
}
else总是与最近的if匹配
找零计算器

#include<stdio.h>
int main()
{
int price;
int bill;
scanf("输入购买的金额:",&price);
scanf("输入支付的票面:",&bill);
if(bill>price)
printf("%d",bill-price);
else
printf("不需要找零钱")
return 0;
}
但是支付的钱不够购买怎么办
#include<stdio.h>
int main()
{
int price=0;
int bill=0;
printf("输入购买的金额:");
scanf_s("%d", &price);
printf("输入支付的票面:");
scanf_s("%d", &bill);
if (bill >= price) {
printf("应该找您:%d", bill - price);
}
else {
printf("您的钱不够");
}
return 0;
}
易错代码!
if(gameover=0)
if(play2move=2)
printf("you turn");
else
printf("GAMEOVER")
最好不要这么写,因为计算机是else和最近的if匹配,但在这条代码中,else并不是与第二个if匹配
所以最优写法是
if(gameover=0){
if(player2move=2)
printf("you turn");
}
else
printf("GAMEOVER");
这样就清晰的看到,else与第一个if匹配
所以要养成在if else后面加上{}的习惯
级联的if-else-if

exp1,2都是并列的
例子

x=0,x>0,x<0都是同阶级的,不存在谁包含谁
高质量代码
例题同上
一
int f;
if(x<0){
f=-1;
}else if(x==0){
f=0;
}else{
f=2*x;
}
printf("%d",f);
二
int f;
if(X<0){
printf("%d",-1);
}else if(x==0){
printf("%d",0);
}else{
printf("%d",2*x);
}
if语句
1.
if(表示条件的逻辑表达式)
{
若干条件语句
}
若表示条件的逻辑表达式的结果不是零,那么执行{}中的语句
若结果为零,那么跳过这些语句不执行,而继续下面的其他语句
2.
若if语句这一行结束并没有;,且后面赋值语句写在if下一行且进行了缩进且有;
这时候就表明这条语句是if的一部分,且if语句也控制这条语句是否执行
if(total>amount)//total>amount这条语句控制了下一行语句是否会执行
total+=amount+10;
两种情况的差别
情况一
#include<stdio.h>
int main()
{
int score;
int PASS=60;
printf("请输入成绩:");
scanf("%d",&score);
printf("你输入的成绩是%d.\n",score);
if(score<PASS)
printf("很遗憾,这个成绩没有及格");
else
print("祝贺你,这个成绩及格了");
printf("再见");
return 0;
}
情况二
#include<stdio.h>
int main()
{
int score;
int PASS=60;
printf("请输入你的成绩:");
scanf("%d",&score);
if(score<PASS)
printf("很遗憾,这个成绩没及格");
else{
printf("祝贺你,这个成绩及格了");
printf("再见");
}
return 0;
}
switch-case

此代码的缺点就是,有可能输入的第一个值就是1,也可能输入的是4,如果是4的话,那么就需要将所有可能试过一边才能输出type==4时printf(再见)
更优解

case1,2,3,4,default是同时进行的
switch(控制表达式){
case 常量;
语句
case 常量;
语句
default;
语句
}
-
switch里的控制表达式只能是整数型结果
-
常量可以是常数,也可以是常熟计算的表达式
break

还是以上一个早上好的例子来说
scanf("%d",&type);
switch(type){
case 1:
case 2:
printf("你好");
break;
case 3:
printf("晚上好");
case 4:
printf("再见");
break;
default;
printf("啊,有什么事");
break;
}
当输入的是1时,但发现1没有语句,代码就会向下运行到case2,因为case2中有break语句,那么输出就是你好,就结束了
循环结构

用选择结构去做

小范围的数还可以这么做,但范围大的话是非常麻烦的
引入while语句

本人学过python表示爽歪歪
while的结构跟if一样

-
{}里是循环体
-
循环体要有改变条件的机会(如过没有跳出循环的条件,就会变成死循环)
验证

do-while循环

while和do-while的区别:
do-while是无论条件满不满足都先至少执行一遍
while是只有条件满足时才执行循环
int x;
scanf("%d",&x);
int n =0;
do
{
x/=10;
n++;
}while (x>0);
printf("%d",n);
猜数游戏

描述思路


但是给的随机数很大

所以随机数就控制在100以内,方便用户去猜
显然这里就要用do-while循环,不管怎么样,总要先让用户先猜一个数,所以先要进行一次循环,这是while循环所不能做到的
完整代码
算平均数

算法


两种循环都可以做,但是很显然while只进行一次就可以,但do-while循环需要做两次,针对这个题,不需要去不看任何条件不管三七二十一就执行一次
整数的分解

int main()
{
int x;
x=12345;
int digit;
int ret=0;
while(x>0){
digit=x%10;//取单个位数上的数
ret=ret*10+digit//将x倒过来
printf("x=%d,digit=%d,ret=%d",x,digit,ret);
x/=10;
}
printf("%d",ret);
return 0;
}
for循环
例子:阶乘
用while循环来做
int n;
scanf("%d",&n);
int fact=1;
int i=1;
while(i<=n){
fact *=i;
i++;
}
printf("%d!=%d\n",n,fact);
用for循环
int n;
scanf("%d",&n);
int fact=1;
int i=1;
for (i=1;i<=n;i++){//i=1是初始条件,i<=n是循环继续的条件,i++是循环每一轮要做的
fact*=i;
}
printf("%d!=%d\n",n,fact);


循环控制变量i只在循环里被使用了,循环外面它没有任何用处。因此,我们可以把变量i的定义写到for语句里面
但是出现了错误,只有c99才能用

循环次数

三种循环的使用区别

break语句(判断素数

但是进行断点测试时发现,即使发现x%i==0,能够整明x是素数了,但无法停止,程序还会往下进行i++,这时就需要break出手啦

有了break,只要有一次x%i==0,就会停止
continue跳过循环
将上面的例题做些变动,加入一个要求:输出每一次循环时,正测试的i的值

9是素数,所以循环的时候会出现两种情况
-
i=2,这类9无法整除的数,不满足9%2==0,所以没办法进入if循环,就会执行printf("%d\n",i)这条语句,然后因为,没有break停止循环的语句,就会进入下一次循环
-
i=3,这类9能够整除,能够证明9是素数的数,满足9%3==0的条件,能够进入if语句且执行到continue会停止循环,跳到循环外的printf("%d\n",i)
循环的嵌套
-
求100以内的素数

-
求50个素数
50个素数的范围就不确定了,这时应用到while循环

其实就是把上一个的外循环换成while循环,但不要忘记循环进行的条件x++
而且需要加一个计数器,因为要前50个素数,循环一次如果发现是素数就+1
还有一种思路就是,依照计数器的次数进行循环

-
凑硬币


但是输出的结果有太多了

那就在程序结束的时候加一个break将执行暂停
函数
引入
1.求素数的和

在for循环内有几行判断素数的代码,与循环外的代码又没有关系,这个时候就可以把它单独拎出来
也就是自己定义一个判断素数的函数

这样一来主函数就变得简便很多,同时也可以反复利用这个函数,在主函数内的任何地方都可以用
2.求和
求出1到10,20到30和35到45的三个和

在这道题中,有三段一模一样的代码,这时可以调用函数来减小运算

函数的定义

函数名(参数值);
-
()起到了表示函数调用的重要作用
-
调用的的话时候即使没有参数也需要()
-
如果没有打上(),会提示warning

意思是表达式的结果没有被使用
-
参数会被按照顺序依次用来初始化函数中

在这张图里被用的就是35,45
例1
void cheer()
{
printf("cheer\n");
}
int main()
{
cheer();
return 0;
}
输出结果为cheer
知识点3:
void cheer()
{
printf("cheer\n");
}
int main()
{
cheer;//没有()
return 0;
}
结果会warning,但函数并没有被调用
回到引入2

函数的返回值
return
一旦遇到return函数就停止,如果return后有值,就送回去一个值
例2 比大小


进行调试取研究return

断点设在第一个引用函数的地方
就进入定义的函数max

max(10,12)所以,a=10,b=12
执行到return,ret为12
继续向下进行

这时的c值为12,因为第一次调用函数结果return为12
继续的话,就是主函数里初始化的a,b的值带入定义函数中
return返回的值为6
那么此时c=6
再继续进行,第三次调用函数返回的值为23
此时c=23
多出口不好

有两个return出口,当需要修改时不方便
没有返回值的函数
-
void函数名(参数表)
-
不能使用带值的return
-
可以没有return
-
调用的时候不能做返回值的赋值
函数原型
函数先后关系
编译器会自上而下分析代码,所以调用函数之前先定义好
函数原型

参数传递
-
如果函数有参数,调用函数时必须传递给它数量,类型正确的值
-
可以传递给函数的值是表达式的结果包括:字面量
变量
函数的返回值
计算的结果

参数的值的类型不匹配
如果函数的参数值的类型是int,但你输入的不是int
例:类型是int,输入了2.4
输出结果会为2,但不会出现错误
传过去的是什么

运行之后发现,主函数的a,b的值并没有互换,虽然定义函数中有a,b,但不是一回事,主函数中的
a的值给了swap里的a,主函数中的b给了swap里的b
所以实际上主函数的a,b的值并没有改变


本地变量
-
函数的每一次运行,就产生了一个独立的变量空间,在这个空间中的变量,是函数的这次运行所独有的,称作本地变量
-
定义在函数内部的变量就是本地变量
-
参数也是本地变量
变量的生存期和作用域

断点调试来进一步阐释生存期和作用域

当断点在y=t时,swap(a,b)里的a,b存在,但作用域不在当前
当执行到swap(a,b)时,离开main的变量空间,跳到定义的swap函数空间内,也就是说即使两个空间内的变量的名称一样,但是没有任何的关系,在swap函数的变量空间内对变量a,b,t做怎样的改变,main函数变量空间内的变量都不发生改变

规则

第二条:
程序运行进入这个块之前,其中的变量不存在,离开这个快,其中的变量就消失了

第三条:在块外定义的变量在块内仍然有效

第四条:在块内定义了与块外同名的变量,则掩盖块外的变量

其他细节
声明时不加参数

如这段代码,声明的时候没有明确告诉参数的类型,但在主函数调用swap函数时,值给的类型时int,但定义swap函数时,参数类型为double
输出:

逗号运算符

C语言不允许函数嵌套定义
int i,j,sum(int a, int b)
定义变量i和j,声明要int a,b作为sum函数的参数,且返回值为int
return(i) ; =return i ;
二者一个意思,前面看起来像错的
数组
引入


int num[100]是可以放100个int型整数的数组
草泥马肯定会忘 到时候再看一遍
基本内容
定义数组

如果变量名称后面没有元素的数量,那么它就是一个变量
什么是数组

例3

数组的单元

有效的下标范围

例

数组a是从0到9,不存在a[10],所以越界出错
但是会看引用的例子,用户很可能输入多于100的数字,但定义数组的时候定义的是100,就会发生了越界都错误,所以要进行调整

就是先让用户输入要输入数字的数量,要输入多少个,直接用用户输入的个数值作为数组的元素数量值,这样就避免了越界的现象
数组创建之后不可以改变
长度为0的数组 int a[0],存在但没用
例4


数组的运算
-
数组的集成初始化
int a[]={2,4,6,7,1,3,5,9,11,13,23,14,32}
-
直接用大括号给出数组的所有元素
-
不需要给出数组的大小,编译器替你数了
测试

测试结果为

变形

测试结果


输出就是:2 0 3 6 0 0 0 0 0 0 0
初始化:
之前的初始化:

定义数组时,直接初始化:

-
数组的大小
用sizeof


-
数组的赋值


search例题!




二维数组

二维数组的遍历

二维数组的初始化

例题:井字游戏

指针
取地址运算
运算符&
获得变量的地址,操作数必须是变量

可以用%p求得字符i地址的大小

或者是

指针


当被调用的时候得到了某个变量的地址
void f(int*p);
当调用的时候也要填f(&i);
例

指针的意义

i的值为6,地址为70,定义的f函数的变量p是存放变量i的地址的,使得f函数拥有访问变量地址的能力,指针p的定义就是:int*p=&i
改变变量地址
*是访问变量地址的单目运算符
*p可以做左值,也就是可以去写它的值
也可以做右值,也就是访问它的值
void f(int *p);
void g(int k);
int main()
{
int i=6;
printf("&i=%p\n",&i)//访问变量i的地址
f(&i);//因为f函数是访问地址的函数,所以调用函数时填的值要加上取地址符&
g(i);
return 0;
}
void f(int *p)
{
printf("p=%p\n",p);
printf("*p=%d\n",*p);
*p=26;//这时改变了i的地址
}
void g(int k)
{
printf("k=%d\n",k);
}
输出结果:

发现i的值已被改变
f,g两个函数的本质就是值的传递
左右值

-
这里的a就是左值,用于标识特定数据对象(用于存储值的数据区域)的名称或表达式
b就是右值,是能复制给可修改左值的量
-
左值指定一个对象可以引用内存中的地址
右值可以用表达式的值这一概念来描述
-
等号不是区分左右值的标准,但是赋值运算符=左侧运算对象,应该是可修改的左值
间接运算符*
获取指针地址上对应的
int*p=&a;//指针变量p存储的是a的地址
int d=*p;//通过获得的a的地址,找到其对应的值,赋值给变量d
*,&
假定有一个变量名为a的变量空间,将变量a初始化为2
*p是取某地址的值,也就是说变量p存储的数据是a的地址,*p表达的是地址上的值2
&a是取值所在的物理位置(也就是地址)
int*即是指针,int*p=&a,这条语句表达的就是,让新变量p存储a的地址
指针的应用场景
一.交换两个值的变量

二.函数返回多个值

由于函数的返回值return只能返回一个,所以选择用指针来解决这个问题
三.函数返回运算的状态,结果用指针返回

常见错误
定义了指针变量,但是没有让它指向任何变量,就开始使用了


指针与数组
将一个普通变量传入函数,得到的是一个值,若将一个指针放入函数,得到的也是一个值,那将数组放入函数会得到什么呢
求同一个变量在不同函数中的大小
函数名 sizeof(变量)
得到的是指针
所以列表在函数里就相当于指针,也就是说sizeof(a)==sizeof(int *)

数组变量是特殊的指针
原理:有一个变量min,变量内的值是2,有一个指针p,p内的值是变量min的地址,所以p指向2,
-
数组不需要取地址符&,但是数组的单元表达的是变量需要用到&,a==&a[0]
-
p[0]是将一个已赋值的变量当作一个数组,那么这个数组的长度就是1,变量被赋予的值也就是数组[0],所以[]可以对指针做,也可以对数组做
-
运算符既可以对指针做,也可以对数组做,且数组的地址是首元素的地址
-
数组变量是const指针,不能被赋值
int a[]=b;//是不可以的
int a[]-->int*const a//const是代表常数,也就是说数组a不能被改变
指针与const

指针是const
一旦得到了某个变量的地址,不能再指向其他变量
int*const q=&i;这条代码的意思就是,q只能指向i,不可以指向别人
*q=26;这条可以执行,因为*q所指向的i不是const,可以改变
q++;不可以,q是const类型,不可以改变
所指是const
const int* q=&i;

i的值可以改变,p可以改变指向,但是不能通过*p改变i的值
两种类型

转换
把非const转成const
void f(const int*x);
int a=15;
f(&a);
const int b=a;
f(&b);
b=a+1;//不可执行
用于当要传递的参数的类型比地址大的时候
优点:既能用较少的字节传递值给参数,又能避免函数对外面的变量的修改
const数组
const int a[]={1 2 3 4 5 6};这条语句是将a数组的所有元素固定住了
所以这种数组必须痛过这种方法初始化赋值,否则写出来没办法赋值
指针运算
char ac[]={0,1,2,3,4,5,6,7,8,9};
char *p=ac;
pritnf("p=%p",p);
printf("p+1=%p",p);
/*输出的p和p+1 只相差1
改用int类型看看*/
int ac[]={0,1,2,3,4,5,6,7,8,9};
int *p=ac;
pritnf("p=%p",p);
printf("p+1=%p",p);
//输出的q和q+1相差4,同时注意是十六进制

*(p+1)
若*p=a[0]
*(p+1)=a[1]
意义

前提是指针指向的是连续的空间,否则没有意义
指针的算术运算
-
给指针加减一个整数
-
递增递减运算(++/--)
-
两个指针相减
char ac[]={0,1,2,3,4,5,6,7,8,9};
char *p=ac;
char *p1=&a[5];
pritnf("p=%p",p);
printf("p+1=%p",p);
printf("*p-p=%d",*p-p)
//输出为p1-p=5
*p++
由于++是后缀,所以先使用p,再加1(取地址动作与p加1动作同步)
通常用于遍历
char ac[]={0,1,2,3,4,5,6,7,8,9};
char *p=ac;
for(i=0;i<sizeof(ac)/sizeof(ac[0]);i++){
printf("%d\n",ac[i]);
}//遍历法一
for(p=ac;*p!=-1;p=++){//p=ac,是指针P指向数组ac的头
printf("%d\n",*p);
}//遍历法二
while(*p!=-1){
printf("%d\n",*p++);
}
*p++的意义是:取出p所指的数据,完事之后顺便把p移到下一个位置去
指针比较

指针的比较,地址大小的比较
0地址

指针的类型

指针的类型转换
void*表示不知道指向什么东西的指针
int*p=&i;
void*q=(void*p);
并没有改变p所指的变量类型,i还是int
补充
指针变量类型
意义:不管是什么类型的指针变量,所存的值都是地址(int类型的值)。那么声明不同类型的作用是什么?答案是规定指针在内存中每次移动的字节数。
例如定义“int *pa = &a”,取值时,int类型占4个字节,指针就从首地址开始移动,读取4个字节。同理,short类型占2字节,指针就移动2字节。通过声明指针类型,告诉指针每次移动多少字节,来获取变量的值。
字符串
字符数组

这样并不是c语言的字符串
若在最后加上一个\0就是了

字符串
-
以0结尾的一串字符
0或\0是一样的,但是和'0'不同
-
0标志字符串的结束,但并不是字符串的一部分
计算字符串长度的时候不包括这个0
-
字符串以数组的形式存在,以数组或指针的形式访问
更多是以指针的形式
-
string.h里有很多处理字符串的函数
字符串变量
char*str="Hello";//str 指针指向一个数组,它的内容是Hello
char word[]="Hello";//有一个数组word,它的内容是Hello
char line[10]="Hello";//有一个数组大小为10,往数组里放了Hello,Hello是5个字符,但占据多大的空间呢
回答第三行代码的问题,由于是c语言的字符串,所以Hello占数组word是六个字节
字符串常量
“Hello”
-
由双引号括起来的叫字符串常量
-
“Hello”会被编译器变成一个字符数组放在某处,这个数组的长度是6,结尾还有表示结束的0
-
两个相邻的字符串常量会被自动连接起来
那如何解决这个问题呢
"内容A""内容B"——>输出就是内容A内容B
"内容A\内容B"——>输出就是内容A 内容B
那接下来做点什么吧
char*s="Hello World";
s[0]='B'
printf("Here!s[0]=%c\n",s[0]);
//此段代码不可行,为什么呢?
char*s="Hello World";
char*s2="Hello World";
printf("s =%p\n",s);
printf("s2=%p\n",s2);
//输出发现,s,s2,被赋予了相同的值,也就是他们所指的位置一致都是0xe1f82
int i=0;//称i为本地变量
printf("&i=%p",&i);
//输出为0xbff1fd6c,一对比发现,i在很大的地方,而s在很小的地方

看图可知,字符串"Hello World"在很小的地方,被称为代码段
如果试图改写这段字符串,那么程序会崩溃掉
但如果非要改呢
char s[]="Hello World"
两者区别就是,前者是指针指向了"Hello World",后者是将"Hello World"放在自己那里

?写成指针的形式还是数组的形式

总结就是:构造字符串用——数组
处理字符串——指针
char*是字符串?
-
字符串可以表达为char*的形式
-
char*不一定是字符,char*表达的是,这有一个指针指向一串字节
-
只有它所指的字符串数组结尾有0,才能说所指的是字符串
字符串输入输出
字符串的赋值
char *t="title";
char *s;
s=t;
图解:

输入输出

输出为

注意
-
不能用运算符对字符串做运算
-
通过数组的方式可以遍历字符串
-
字符串字面量可以用初始化字符数组
本文介绍了C语言的基础知识,包括变量的定义与赋值,常量的使用,输入输出函数如scanf和printf的运用,以及如何进行字符串操作。文章还详细讲解了不同类型的循环结构如while、for和do-while,以及如何使用break和continue控制循环。此外,函数的定义、调用与参数传递也被提及,特别是涉及指针时如何交换变量值和作为函数返回值的情况。最后,文章讨论了数组的使用,包括一维和二维数组,以及字符串在C语言中的处理方式。
1804

被折叠的 条评论
为什么被折叠?



