標準c基礎知識三
數組是把一組相同類型的數據放到一起,便于管理;在內存中一定是連續擺放,;每個元素分配一個下標(從0開始)
#include <stdio.h>
int main()
{
int a[10];//定義時,方括號內是元素個數,要求非負整數字面量//目前這樣的話,里面都是垃圾數據,最好要進行初始化
int i;
for (i=0;i<10;i++){
printf("%d",a[i]);//a[i];使用時,方括號內是下標;(0-元素個數-1)
}
printf("\n");
int num[4]={30,16,22,18};//數組初始化用{}大括號括起來;數量在這里是4,數據不能多可以少;少的部分全部用數值0(注意是數值0,假設是char數組,在這里用"\0"來填充)來填充;
for (i=0;i<4;i++){
printf("%d",num[i]);
printf("\n");
}
int b[5]={11};
for(i=0;i<5;i++){
printf("%d",b[i]);
printf("\n");
}
char c[10]={'c','s','d','1','0','0','7'};//數組中有多余的元素則放不下
for(i=0;i<10;i++){
printf("[%c]%d",c[i],c[i]);
printf("\n");
}
return 0;
//a數組賦值
//a=123;X;錯誤數據類型不匹配
//a={10,20,30,40};X,錯誤,賦值不能用{}
//數組可以初始化不可以賦值;但可以針對每個數組元素進行賦值
//數組是一個集合,可以初始化時賦值不可以后期單獨賦值;但可針對每個元素賦值
a[1]=10,a[2]=20,a[3]=30,a[4]=40;
printf("請輸入5個整數:");
for(i=5;i<10;i++){
scanf("%d",&a[i]);//一定要記得取地址&,要不然會段錯誤
}
for(i=0;i<10;i++){
printf("%d",a[i]);
printf("\n");
}
}
數組在內存中是連續存放的,只要知道第一個元素的地址,也就知道了元素的地址;
可以理解為:“數組名是第一個元素的地址,下標是偏移量(與第一個元素距離)”
#include <stdio.h>
int main()
{
int a[5]={11,22,33,44,55};
printf("a=%p\n",a); //%p:address
int i;
for (i=0;i<5;i++){
printf("&a[%d]=%p\n",i,&a[i]);//依次輸出每個元素的地址;
}
*a+=100;//意思是將第一個元素增加100 //通過*訪問地址來取變量
printf("%d\n",a[0]);
for(i=0;i<5;i++){
printf("a+%d=%p\n",i,a+i);//在這里要理解a+i的變化;更換數組類型為int,short int觀察;;;a+i==&a[i];兩者等價;a[i]==>*(a+i)
}
}
數組越界
vi outrange.c
#include <stdio.h>
int main()
{
int x=123;
int a[5]={11,22,33,44,55};
int y=456;
int i;
for (i=0;i<5;i++)//如果把這里變更為for(i=-2;i<8;i++) 則前面出現了2個垃圾數據,后面也會有3個垃圾數據
{
printf("%d ",a[i]);
}
printf("\n");
printf("x=%d,y=%d\n",x,y);
for (i=-2;i<8;i++)
{
a[i]=0;
}
printf("x=%d,y=%d\n",x,y);
return 0;
}
編譯器并不保證變量的存放順序按照變量的定義順序來存放
用數組的時候下標切勿越界;//越界訪問數據可能訪問到無法預知的數據
//越界存放數據可能會破壞其他變量的值
//越界存放數據甚至可能導致程序崩潰
C語言里面用的字符串,abcdefghijkl,放在內存里面怎么區分呢?是abcdefghijkl,還是abcdef ghijkl
實際上在內存中存放不是連續的而是abcdef\0在結束位置有個\0來進行相隔
char[],可以用來放字符串
#include <stdio.h>
int main()
{
char a[4]={'a','b','c','d'};//a是一個字符數組,不是字符串,
printf("%s\n",a);//輸出不一定是字符串,如果沒有\0就不是字符串,可能在abcd之后有亂碼輸出;
char s[8]={'h','e','l','l','o','\0','w','o'};
printf("%s\n",s);//次次輸出為hello
printf("%s\n",s+2);//輸出為llo 理解:s為第一個元素的地址,+2
printf("%s\n",s+6);//輸出wo后面可能會有亂碼出現
char str[800];
printf("請輸入一個字符串:");
scanf("%s",&str);//碰到空格字符結束 gets(str);可以讀取一行碰到換行符結束,但現在基本上已經拋棄2392454762
printf("%s\n",str);
printf("請輸入一行文字:\n");
scanf("%*[^\n]%*c")
return 0;
}
{
char c;
do
scanf("%c",&c);
while(c!='\n');
}
<====>scanf("%c",&str[0]);
printf(str);printf("\n");//printf輸入內容中有格式占位符時就會出問題
vi string.c
#include <stdio.h>
int main()
{
char a[100]={'h','e','l','l'};
//char a[100]="hello,world";//與上面等價
printf("%d\n",sizeof("hello world!"));//輸出13個字符,其中12個有效字符,1個\n字符
printf("%c\n","cool007"[3]);//輸出為l
printf("%s\n","cool007"+3);//輸出為l007
return 0;
}
理解數組名本身是不占用存儲空間的。作為數值的時候只是代表數組的第一個元素的地址。
vi arrayname.c
#include <stdio.h>
int main()
{
int a[5];
double d[3];
char s[9];
printf("%d,%d,%d\n",sizeof(a),sizeof(d),sizeof(s));//最后輸出為20,24,9
//怎么來的呢?
//int為32位,即每個元素4個字節;a數組有5個元素,則為20個字節,同理理解數組d和s。
return 0;
}
數組第一個元素的地址(*a);數組開始的地址(&a)//其物理地址是一樣的,但含義不一樣
a[1]=====>(*&a)
字符串的操作:把某個字符串放到某個地方
#include <stdio.h>
#include <string.h>
int main()
{
char a[100]="hello,world";
puts(a);
strcpy(a,"good afternoon!");//作用是復制字符串,把某個字符串復制到某個地方去
puts(a);
strcat(a,"dear friends!");//在一個字符串的末尾再追加一個字符串;要確保目的地有足夠的空間來存放追加的內容
puts(a);
printf("%d,%d\n",sizeof(a),strlen(a));//計算a數組中一個字符串的長度;字符數組才能用;計算結果不包括反斜杠0
//strchr(a,‘f’);//在一個字符串中找一個字符;代表的是找到一個地址;沒找到代表的是找到一個空地址
printf("%s\n",strchr(a,'f'));//從f開始到結尾
//printf("s\n",strchr(a,'k'));//字符串中無K,輸出為空地址輸出為段錯誤
printf("%s\n",strrchr(a,'f'));//從右往左找
puts(strstr(a,"ear"));//從a里面尋找一個字串
//字符串的比較
char b[6]="hello";
if (b=="hello")
printf("相等\n");
else
printf("不相等\n")
printf("%p,%p\n",b,"hello");
//b本身是一個數組;hello本身也是一個字符數組;雖然內容相同,但是其地址不相同
//如果想比較兩個數組的內容是否相等,則用strcmp(b,"hello");如果兩個字符串相等,帶回來的數值為0,否則,第一個大,則為正;第一個小為負
//實際上是比較的ascii碼
//字符串常量一般存儲在只讀存儲空間里,程序只有讀權限
//"hello"[0]='H';//編譯錯誤:給只讀位置賦值
return 0;
}
字符串總是在一個字符數組中,必須有一個\0結束;這是對的
一個字符數組就是一個字符串,這是不一定的。(必須有\0結束才行)
多個一維數組組合在一起組合成一個二維數組如
int a[10]
int b[10]
int c[10]
int d[10]
int e[10]
int x[5];//x的類型為int[5]
int x[5][10];//5個int[10]的一維數組
#include <stdio.h>
int main()
{
int a[3][5]={
{1,2},
{3};
{4,5}
};
int i,j;
for (i=0;i<3;i++)
{
printf("%p\n",a[i]);//顯示
for (j=0;j<5;j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}
vi structure.c
//結構是C語言中定義新類型的方法
#include <stdio.h>
#include <string.h> //后面使用了strcpy函數
typedef enum gender{MALE,FEMALE} gender;
//typdef enum gender gg;
typedef struct person{
//
char name[20];
int age;
double income;
enum gender s;
}person; //切記這里有個;號
typedef char A[20];//給char[20]起別名
int main()
{
A str="good";//str的類型是char[20]
puts(str);
person a;
person b={"sxl",MALE,100,8005};
printf("%s是一位%d的%s,月薪%g\n",b.name,b.age,b.s=MALE?"帥哥":"美女",b.income);
peson c={age:18,s:FEMALE,name:"老姐",income:9876.5};
printf("%s是一位%d的%s,月薪%g\n",c.name,c.age,c.s=MALE?"帥哥":"美女",c.income);
person d=c;//內容相同,但是是兩個獨立的實體;只是復制了一下而已
printf("&c=%p,&d=%p\n",&c,&d);
a=b;
a.age=20;
strcpy(a.name,"哥");//不能用a.name=...
printf("%s是一位%d的%s,月薪%g\n",a.name,a.age,a.s=MALE?"帥哥":"美女",a.income);
printf("--------\n");
person p[5]={
a,
b,
c,
d,
{"帥",MALE,6,0}
};
int i;
for (i=0;i<5;i++){
printf("%s是一位%d的%s,月薪%g\n",p[i].name,p[i].age,p[i].s=MALE?"帥哥":"美女",p[i].income);
}
printf("請輸入姓名、性別(M/F)、年齡、收入:\n");
char s;
scanf("%s %c%d%lf",&a.name,&s,&s.age,&a.income);
a.s=(s=='M'||s=='m')?MALE:FEMALE;
}