11.11

计算字串的长度

  1. #include<stdio.h>
  2. int str_len(char str[]){
  3. int i=0;
  4. while(ste[i]!='\0'){
  5. i++;
  6. }
  7. return i;
  8. }
  9. int main(){
  10. char str_[i]="hello world"; //当字串数字恰好等于不加'\0'是的长度时,即i=11时,语法合法,但此阵列不能运用于函式中。当i=15时,系统将会自动补'\0'。
  11. printf("length:%zu\n",sizeof(str)); //有的版本用%u或%lu
  12. printf("length:%d\n",str_len(str));
  13. return 0;
  14. }

输入一段字串

  1. #include<stdio.h>
  2. void readch(char[]);
  3. int main(){
  4. char str[15];
  5. readch(str);
  6. printf("%s\n",str);
  7. return 0;
  8. }
  9. void readch(char str[]){
  10. int i=0;
  11. while(1){
  12. scanf("%c",&str[i]);
  13. if(str[i]=='\n')
  14. break;
  15. i++;
  16. }
  17. str[i]='\0'; //将\n换为\0
  18. }

当输入字串时,没有立马存入记忆体中,而是先存在stdin中,当按enter后,scanf会去stdin中找新录入的东西

解决溢位的问题

  1. #include<stdio.h>
  2. void readch(char[],int);
  3. int main(){
  4. char str[15];
  5. readch(str,14);
  6. printf("%s\n",str);
  7. return 0;
  8. }
  9. void readch(char str[],int){
  10. int i=0;
  11. for(i=0;i<n;i++){
  12. scanf("%c",&str[i]);
  13. if(str[i]=='\n')
  14. break;
  15. }
  16. str[i]='\0';
  17. }

但是scanf会忽视空格

当输入格式错误时

  1. #include<stdio.h>
  2. int main(){
  3. int num;
  4. whilr(scanf("%d",&number)!=1){
  5. printf("Error: invalid input\n");
  6. }
  7. printf("%d\n",num);
  8. return 0;
  9. }

但失败后,错误的格式仍然留在stdin中,再次输入时仍然会错误

字串在函式中传递时也不能复制,且也不能a=v直接将字串赋值

指标

指标是一种资料型别,用来存储记忆体位址

宣告语法

int *a; 存储int值得位置

int **b; 存储*b的位置即存储存储b位置的位置

double *c=&d 找出d的位置存储在*c里

取址运算子:&

间接运算子:*

A=8

*Aaddr 中*是一个运算,取Aaddr所存的记忆体的位址上的值,即取得以该记忆体位址起始得变数

即*Aaddr==8

Aaddr=9 时,A的值也会改变,即此时A==9

*&*&*&*&*&A *&可以相消

当函式中复制的是位置是,就可以把本尊改掉

  1. #include<stdio.h>
  2. void swap(int *a,int *b);
  3. int main(){
  4. int a=3,b=5;
  5. swap(&a,&b);
  6. printf("%d,%d",a,b);
  7. return 0;
  8. } //交换两个值
  9. void swap(int *a,int *b){
  10. int t;
  11. t = *a;
  12. *a = *b;
  13. *b = t;
  14. }
  1. #include<stdio.h>
  2. void sort(int *,int *);
  3. void swap(int *,int *);
  4. int main(){
  5. int a,b;
  6. scanf("%d %d",&a,&b);
  7. sort(&a,&b);
  8. printf("%d,%d\n",a,b);
  9. return 0;
  10. }
  11. void sort(int *a,int *b){ //排序
  12. if(*a>*b){
  13. swap(a,b);
  14. }
  15. }
  16. void swap(int *a,int *b){
  17. int t;
  18. t = *a;
  19. *a = *b;
  20. *b = t;
  21. }

能复制值就不要复制位置

  1. int a[5];
  2. &a[0]+1==&a[1];
  3. &a[1]-1==&a[0];
  4. &a[0]+&a[1]; //不合法
  5. &a[5]-&a[2]==3; //合法,表示有几个间隔

阵列性别可隐形转换为该阵列第一个元素记忆体位址的指标

  1. int v[5];
  2. int *n=v;
  3. n ==&v[0]; *n ==v[0];// *n=0即v[0]=0
  4. n+1==&v[1]; *(n+1)==v[1];
  5. n+2==&v[2]; *(n+2)==v[2];

循序存取阵列元素

  1. #include<stdio.h>
  2. int main(){
  3. intv[5]={1,2,3,4,5};
  4. int *n=v;
  5. while(n!=){
  6. printf("%d\n",*n++); //*(p++)
  7. }
  8. return 0;
  9. }

a[b]就是*(a+b)阵列在函式间的传递就是利用次

  1. int v[5];
  2. int *n=v;
  3. n[0]==*n; //等同于v[0]
  4. n[1]==*(n+1);
  1. int main(){
  2. int v[5];
  3. int *p=v;
  4. while(p!=v+5){ //v+5:v隐形转型成了指标,就相当于&v[5]
  5. *p++=0;
  6. }
  7. return 0;
  8. }

双引号可直接隐形转型为指标

指标与字符串

char strA[]="test";  //宣告了一个字串
char *strB = "test";  //没有宣告,直接取了地址,系统会自动分配一个位置来存储这个字串

strA[0] ='T';  
strB[0] ='T';  //  是未定义行为,因为是系统给分配的空间,只能读取,不能改动,但能整串换掉

strA ="Test";  //编译失败,,阵列不能直接赋值,阵列变数不能放到等号的左边
strB ="Test";  //会在存储一份,而不是覆盖原来的

const修饰字

资料型别被const修饰的变数在初始化之外不能再被赋值

const int b = 5;

const int b[3]={5,6,7};