20240629ky学习笔记自用
数据类型--构造类型(数组、结构体)
场景特点:
-
数据类型相同
-
使用过程需要保留原始数据?
声明数组
-
命名规则遵循标识符命名规则(即和命名变量名相同)。
-
方括号中的最好是常量表达式,表示数组长度。
-
常量表达式:常量和符号常量,不能包括变量。也就是C语言不允许对数组的大小做动态定义。
int n=10;
int a[n]; //老式的是不行的,请你机试时候不要这样用。
int a[10];
-
数组长度大小为0没有意义。方括号不能写成圆括号。不能用变量声明数组大小。
-
初始化数组
-
int a[10]={1,2,3,4,5}; 其余没有赋值的自动为0.
-
全为0,可以写int a[10]={0};
-
int a[]={1,2,3,4,5},计算机会自动识别长度为5。但是初始不建议,乖乖写上就好。
-
不能写成int a[10]; a[10]={1,2,3,4,5,6,7,8,9,10}
数组的访问越界
-
操作系统对内存中的每个位置也给予了编号,对于windows32位控制台应用程序而言,编号就是从0x 00 00 00 00到0xFF FF FF FF,总计2的32次方,大小为4G。
-
访问越界,c语言不会检查你的越界,需要自己注意!
#include <stdio.h>
int main() {
int a[5]={1,2,3,4,5};
int j=20;
int i=10;
a[0]=-1;
a[5]=6; //访问越界,c语言不会检查你的越界
a[6]=7;
printf("a[0]=%d\n",a[0]);
printf("i=%d\n",i);//i竟然发生改变。
return 0;
}
数组传递
-
数组名传递到子函数后,子函数的形参接收到的是数组的起始地址,8个字节。
-
数组的长度是传递不过来的。
-
子函数内可以改变数组的值。
-
对传递数组的函数,print(a,5);
-
不要写a[5],这样是访问第6个元素,访问越界。
-
也不要写a[]。
-
#include <stdio.h>
//子函数把某一个常用功能封装起来。
//子函数传递不来数组长度,所以需要多一个length参数。
void print(int a[5],int length) //这里不用写5,数组的长度是传递不过来的。这里写b也行,不用同步主函数里面的a。
{
int i;
//数组名传递到子函数后,子函数的形参接收到的是数组的起始地址,8个字节。(64位)
//所以不能把数组的长度传递给子函数。所以sizeof(a)得到的会是8.
// for(i=0;i<sizeof(a)/sizeof(int);i++)
// for(i=0;i<5;i++)
for(i=0;i<length;i++)
{
printf("%3d",a[i]);
}
a[3]=20; //子函数内可以改变数组的值。
printf("\n");
}
//main函数就是主函数。
int main() {
int a[5]={1,2,3,4,5};
// print(a);
//这里不要写a[5],这样是访问第6个元素,访问越界。
//也不要写a[]。
print(a,5);
printf("%3d\n",a[3]);
return 0;
}
字符数组
初始化
-
使用%s来输出一个字符串,直接把字符数组名放在printf后面的位置。
-
初始化1:每一个字符必须要用单引号引起来,但是这样没有结束符,用%s输出的时候会出现乱码!
-
初始化2:双引号。注意c语言规定字符串的结束标志为'\0'。所以char a[10]最长存储9个字符,剩余一个存'\0'。
#include <stdio.h>
//模拟printf输出%s情形
void print(char a[])
{
int i=0;
// while(a[i]!='\0')也可以
while(a[i])// 当走到结束符时,循环结束。
{
printf("%c",a[i]);
i++;
}
a[0]='H';
printf("\n");
}
//字符数组
int main() {
char c[3]={'d','a','b'};//每一个字符必须要用单引号引起来,但是这样没有结束符,用%s输出时候会出现乱码!!!
char a[6]={"hello"};//使用这种方式初始化。不要写成a[5]!!!
char b[5]={"hello"};
print(a);
printf("%s\n",a);//使用%s来输出一个字符串,直接把字符数组名放在printf后面的位置。
printf("%s\n",c);//有乱码
printf("%s\n",b);//有乱码
return 0;
}
scanf字符串
-
字符数组名c中本来就存储了数组的起始地址,因此不需要取地址!!!
-
scanf的%s输入完成后会自动填一个'\0'进去。
-
sacnf的%s读到空格也不会继续往下读。
-
scanf的%s%s读到空格,就开始匹配第二个%s,但是会清除读到的那个空格,和%d、%f一样会忽略空格。
-
sacnf的%c读到空格会存储,反正记得连续输入时在%c前面要加一个空格。
#include <stdio.h>
int main() {
char c[10]={'1','2','3','4','5','6','7','8'};
char a[10],b[10],i[10],j[10];
int d,k;
char g,m;
float f,h;
scanf("%s",c);//字符数组名c中本来就存储了数组的起始地址,因此不需要取地址。
//sacnf的%s读到空格也不会继续往下读。
//scanf的%s%s读到空格,就开始匹配第二个%s,但是会清除读到的那个空格,和%d、%f一样会忽略空格。
//sacnf的%c读到空格会存储?反正记得在%d和%c之间要加一个空格。
fflush(stdin);
scanf("%s%s",a,b);
fflush(stdin);
scanf("%s %s",i,j);
fflush(stdin);
scanf("%d%f%c",&d,&f,&g);
fflush(stdin);
scanf("%d%f %c",&k,&h,&m);
//scanf输入完成后会自动填一个'\0'进去。
printf("c=%s\n",c);
printf("a=%s,b=%s\n",a,b);
printf("i=%s,j=%s\n",i,j);
printf("dfc=%d,%f,%c\n",d,f,g);
printf("df c=%d,%f,%c\n",k,h,m);
return 0;
}
gets函数、puts函数
char *get(char *str);
int puts(char *str);
-
puts等价于printf("%s\n",c);
-
puts内放的参数是字符数组名。
-
gets中放入我们字符数组的数组名即可。
-
gets读到'\n'就不读,然后会在数组最后存上'\0'.
-
windows下使用VS的集成开发环境,不能使用gets,使用fgets(c,sizeof(c),stdin);
#include <stdio.h>
int main() {
char c[20];
gets(c);//gets中放入我们字符数组的数组名即可。
//gets读到'\n'就不读,然后在数组最后存上'\0'
puts(c);//puts等价于printf("%s\n",c);
//puts内放的参数是字符数组名。
return 0;
}
str系列字符串操作函数
-
strcpy、strcat、strcmp、strlen都可以放字符串常量。
-
但是strcpy、strcat第一个位置要放空间,不能放字符串常量。
-
strlen统计字符串长度,但是不会统计'\0'。
-
strcmp(a,b):a大于b,返回的是正值;相等是0;a小于b,返回负值。
#include <stdio.h>
#include <string.h>
int mystrlen(char c[])
{
int i=0;
while(c[i])//找到结束符后,循环结束。
{
i++;
}
return i;
}
int main() {
char c[20],d[100]="world";
char e[100];
int len;
gets(c);
puts(c);
len=strlen(c);//统计字符串长度,不会统计'\0'
printf("len=%d",len);
len=mystrlen(c);
printf("my len=%d",len);
strcat(c,d);//把d中的字符串拼接到c中。
puts(c);
strcpy(e,c);//把c中的字符串复制到e中。
puts(e);
printf("c?d=%d\n",strcmp(c,e));
printf("c?d=%d\n",strcmp(c,d));
printf("c?d=%d\n",strcmp(c,"how"));
//c大于”how“,返回的是正值;相等是0;c小于”how“,返回负值。
//注意比较的不是长度,是abcdef。
//strcpy、strcat第一个位置要放空间,不能放字符串常量。
//strcpy、strcat、strcmp、strlen都可以放字符串常量。
return 0;
}
题目
输入n个数,出现2的次数
-
注意开始的count需要初始化为0!!
#include <stdio.h>
int main() {
//输入n个数,出现2的次数
int length,i;
int arr[100];
scanf("%d",&length);
for(i=0;i<length;i++)
{
scanf("%d",&arr[i]);
}
int count=0;
for(i=0;i<length;i++)
{
if(arr[i]==2)
{
count++;
}
}
printf("%d\n",count);
return 0;
}
逆转之后判断大小,原字符更大则输出1.
-
可以直接在vers[100]={0},初始化!存上结束符!!
-
注意对于strcmp输出的是负数,不一定就是-1.
#include <stdio.h>
#include <string.h>
int main() {
//逆转之后判断大小,原字符大输出1.
char c[100];
gets(c);
char vers[100];
int i=strlen(c),j=0,result;
vers[i]='\0'; //可以直接在vers[100]={0},初始化!
while(i)
{
i--;
vers[j]=c[i];
j++;
}
//可以使用for循环
// for(i=0;j=strlen(c);i++,j--)
// {
// vers[j]=c[i];
// }
// printf("%s\n",c);
// puts(vers);
//注意对于strcmp输出的是负数,不一定就是-1.
result=strcmp(c,vers);
if(result>0)
{
result=1;
}else if(result<0){
result=-1;
}else{
result=0;
}
printf("%d\n",result);
return 0;
}